multiple definition of template specialization when using different objects

后端 未结 4 620
清酒与你
清酒与你 2020-11-30 18:23

When I use a specialized template in different object files, I get a \"multiple definition\" error when linking. The only solution I found involves using the \"inline\" func

相关标签:
4条回答
  • 2020-11-30 19:03

    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.

    0 讨论(0)
  • 2020-11-30 19:04

    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.

    0 讨论(0)
  • 2020-11-30 19:09

    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.

    0 讨论(0)
  • 2020-11-30 19:16

    Here is some piece of C++11 standard related to this issue:

    An explicit specialization of a function template is inline only if it is declared with the inline specifier or defined as deleted, and independently of whether its function template is inline. [ Example:

    template void f(T) { /* ... / } template inline T g(T) { / ... */ }

    template<> inline void f<>(int) { /* ... / } // OK: inline template<> int g<>(int) { / ... */ } // OK: not inline — end example ]

    So if you make some explicit(aka full) specializations of templates in *.h file, then you will still need inline to help you get rid of the violation of ODR.

    0 讨论(0)
提交回复
热议问题