c++inlinetemplate-specializationone-definition-ruletemplate-function

Inlining Template Specialization


If I have a header foo.h which I include all over my project, it seems to work fine when all it contains is:

template<typename T>
void foo(const T param) {
    cout << param << endl;
}

But I get one definition rule (ODR) errors when I add a specalization to foo.h:

template<>
void foo(const bool param) {
    cout << param << endl;
}

Obviously I can solve this by inline'ing the specialization. My question is, why do I need to? If the template doesn't violate ODR, why does a specialization?


Solution

  • An explicit specialization is not implicitly inline. It must be explicitly made inline.

    [temp.expl.spec]/12

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

    template<class T> void f(T) { /* ... */ }
    template<class T> inline T g(T) { /* ... */ }
    
    template<> inline void f<>(int) { /* ... */ }   // OK: inline
    template<> int g<>(int) { /* ... */ }           // OK: not inline
    

     — end example ]

    So you have to do it, because the standard says you have to do it.