Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

explicit specialization of class method - symbol already defined

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?

like image 366
xtofl Avatar asked Apr 23 '13 08:04

xtofl


People also ask

What is explicit template specialization?

Explicit (full) specialization Allows customizing the template code for a given set of template arguments.

How to define template class in Cpp?

Templates in c++ is defined as a blueprint or formula for creating a generic class or a function. To simply put, you can create a single function or single class to work with different data types using templates. C++ template is also known as generic functions or classes which is a very powerful feature in C++.


1 Answers

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.

like image 192
Andy Prowl Avatar answered Sep 23 '22 11:09

Andy Prowl