문제

The One Definition Rule states that a program should contain one definition of every non-inline function. For members of template classes, this not entirely clear to me:

 ///////////
 // Tfoo.h
 template<typename T> class A { 
     void foo(){} 
 };

 ///////////
 // intfoo.h
 #include <Tfoo.h>
 template<> class Foo<int> { 
     void foo(); // declaration only
 }; 
 /*inline*/ void Foo<int>::foo(){} // definition

 ///////////
 // X.cpp
 #include <intfoo.h>

 ///////////
 // Y.cpp
 #include <intfoo.h>

In this case, both clientX.obj and clientY.obj have a definition of Foo<int>::foo. The linker complains that this symbol is defined more than once:

Y.obj : error LNK2005: "private: void __thiscall Foo<int>::foo(void)" 
(?foo@?$Foo@H@@AAEXXZ) already defined in X.obj

When I prepend inline to the definition of Foo<int>::foo(), all goes well and the linker is happy. Also when I define them the method in a separate compilation unit (e.g. intfoo.cpp).

(Note: this solution was suggested in https://stackoverflow.com/a/1481796/6610)

Possibly a misconception, but aren't member functions of template classes always 'inline'? What is the rule here?

도움이 되었습니까?

해결책

A member function of an explicit specialization of a class template is just like a member function of a non-template class. After all, an explicit specialization is a concrete class that does not depend on any template parameter.

If you put its definition in a header file that is included by several translation units, the compiler will produce object code for that function while processing each of those translation units.

Eventually, the linker will complain about multiply defined symbols. The inline keyword prevents this behavior, just like it does for regular non-template functions or regular member functions of non-template classes.

다른 팁

You can move the definition of the explicit specialization

void Foo<int>::foo() {}

into a .cpp file. Leave a declaration in .h:

template<>
void Foo<int>::foo();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top