Why the common template method definition doesn't match the template class specialization?
c++, c++11, templates
Solution
The primary class template `template <class T, class U = T> class A` and the partial specialization `template <class T> class A<T, T>` are two distinct template definitions. After they've been defined, whenever you refer to the class template name `A`, the primary template and all partial specializations will always be considered.
Whenever you instantiate `A` with either a single template argument, or two arguments of the same type, it'll form a better match for the specialization you've provided, and the primary template is not considered.
In your example, because of the partial specialization you've provided, there's no way to match the primary template, regardless of the default template argument, if you try to instantiate `A` with a single template argument, or two of the same type.
The solution, of course, is to provide the definition for `A<T, T>::f()`
template <class T>
void A<T, T>::f() {}
EDIT: In the presence of partial specializations, the rules for matching them are given by (from N3797) §14.5.5.1/1 [temp.class.spec.match]
When a class template is used in a context that requires an instantiation of the class, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations. This is done by matching the template arguments of the class template specialization with the template argument lists of the partial specializations. — If exactly one matching specialization is found, the instantiation is generated from that specialization. — If more than one matching specialization is found, the partial order rules (14.5.5.2) are used to determine whether one of the specializations is more specialized than the others. ... — If no matches are found, the instantiation is generated from the primary template.
In your example the first rule applies, and the compiler doesn't even get to the 3rd rule.
Problem
I have the following code: ``` template <class T, class U = T> class A { public: void f(); }; template <class T> class A<T, T> { public: void f(); // Unaltered method. // Some differences. }; template <class T, class U> void A<T, U>::f() {} int main() { A<int> a; a.f(); return 0; } ``` The `clang++ -std=c++11 test.cc` gives me an error: `undefined reference to 'A<int, int>::f()'` Why the provided definition of method `f()` doesn't apply to the class `A<int, int>`?