13 Templates [temp]

13.7 Template declarations [temp.decls]

13.7.5 Class template partial specializations [temp.class.spec]

13.7.5.1 Matching of class template partial specializations [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.
A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list, and the deduced template arguments satisfy the associated constraints of the partial specialization, if any.
Example
:
template<class T1, class T2, int I> class A             { };    // #1
template<class T, int I>            class A<T, T*, I>   { };    // #2
template<class T1, class T2, int I> class A<T1*, T2, I> { };    // #3
template<class T>                   class A<int, T*, 5> { };    // #4
template<class T1, class T2, int I> class A<T1, T2*, I> { };    // #5

A<int, int, 1>   a1;                    // uses #1
A<int, int*, 1>  a2;                    // uses #2, T is int, I is 1
A<int, char*, 5> a3;                    // uses #4, T is char
A<int, char*, 1> a4;                    // uses #5, T1 is int, T2 is char, I is 1
A<int*, int*, 2> a5;                    // ambiguous: matches #3 and #5
— end example
 ]
Example
:
template<typename T> concept C = requires (T t) { t.f(); };

template<typename T> struct S { };      // #1
template<C T> struct S<T> { };          // #2

struct Arg { void f(); };

S<int> s1;                              // uses #1; the constraints of #2 are not satisfied
S<Arg> s2;                              // uses #2; both constraints are satisfied but #2 is more specialized
— end example
 ]
If the template arguments of a partial specialization cannot be deduced because of the structure of its template-parameter-list and the template-id, the program is ill-formed.
Example
:
template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {};     // error

template <int I> struct A<I, I> {};         // OK

template <int I, int J, int K> struct B {};
template <int I> struct B<I, I*2, 2> {};    // OK
— end example
 ]
In a type name that refers to a class template specialization, (e.g., A<int, int, 1>) the argument list shall match the template parameter list of the primary template.
The template arguments of a specialization are deduced from the arguments of the primary template.