Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top