I am hoping someone can point out the correct way to specialize a method in a template class while using \"extern template class\" and \"template class\" for explicit instan
Adding this answer to address the question in the title (template instantiation, and not necessarily template method instantiation).
This much resembles function declaration/definition.
extern template class
is a declaration and should generally go in the header.template class
is a definition and should generally go in the cpp.More info here.
extern template class A<long>;
This line says that A<long>
is to be explicitly instantiated according to the definitions the compiler has already seen. When you add a specialization later, you break that meaning.
Add a declaration of your specialization to the header file.
template <typename T> struct A { /*...*/ };
template<> int A<long>::get() const;
extern template class A<int>;
extern template class A<long>;
In general, it's best to put as many specialization declarations as possible in the same header file as the primary template, to reduce surprises for the compiler about which declaration should be used for any particular instantiation.
Notice that the extern template
declaration isn't necessary if you're dealing with a single template entity (as opposed to this case, where we have to instruct the compiler about both the class A<long>
and the function A<long>::get()
). If you want to specialize a function template in another translation unit, it suffices to write just template<>
.
template<typename T> int freeGet() { return 0; } // you can even add "inline" here safely!
template<> int freeGet<long>(); // this function is not inline (14.7.3/12)
But you must have the <>
there. If you omit the <>
, the declaration turns into an explicit instantiation of the default implementation (return 0
), which is likely not what you wanted! Even if you add extern
, the compiler is allowed to inline that default implementation; if your code unexpectedly breaks when you pass -O2
, you might have accidentally omitted the <>
somewhere.