multiple definition of template specialization when using different objects

Intuitively, when you fully specialize something, it doesn't depend on a template parameter any more -- so unless you make the specialization inline, you need to put it in a .cpp file instead of a .h or you end up violating the one definition rule as David says. Note that when you partially specialize templates, the partial specializations do still depend on one or more template parameters, so they still go in a .h file.


The keyword inline is more about telling the compiler that the symbol will be present in more than one object file without violating the One Definition Rule than about actual inlining, which the compiler can decide to do or not to do.

The problem you are seeing is that without the inline, the function will be compiled in all translation units that include the header, violating the ODR. Adding inline there is the right way to go. Otherwise, you can forward declare the specialization and provide it in a single translation unit, as you would do with any other function.


You've explicitly instantiated a template in your header (void Hello<T>::print_hello(T var)). This will create multiple definitions. You can solve it in two ways:

1) Make your instantiation inline.

2) Declare the instantiation in a header and then implement it in a cpp.