Search code examples
c++specializationclass-template

Class template member specialization


I'm specializing member functions of a template class in a header file like so:

#pragma once

#include <iostream>

template<class T>
struct Test
{
    void Print() { }
};

template<>
void Test<int>::Print()
{
    std::cout << "int" << std::endl;
}

Is it correct to put the specialization in a header file (without it being inline), or should it be in a cpp file? It compiles fine as shown above (using VS2012), but I'm rather surprised I don't get multiple definition linker errors.


Solution

  • The ODR requires exactly one definition for non-inline functions that are ODR-used (that roughy means, for functions, being potentially called).

    Quoting n3485, [basic.def.odr]

    4 Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.

    Then, there's an exception for templates (i.e. not for functions):

    6 There can be more than one definition of a class type [...], class template, non-static function template, static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified in a program provided that [...]

    [emphasis mine]

    An explicit specialization of a template is not a template. For example, an explicitly specialized class template is a class (with a strange name). Therefore, your assumption is correct and multiple definitions for explicitly specialized members of class templates violate the ODR.

    With g++4.8.1, I even get a linker error in such a program; note that I have ODR-used the function. No diagnostic is required for a violation of the ODR.