When you instantiate a class template, the compiler creates a definition based on the template arguments you have passed. Alternatively, if all those template arguments match those of an explicit specialization, the compiler uses the definition defined by the explicit specialization.
A partial specialization is a generalization of explicit specialization. An explicit specialization only has a template argument list. A partial specialization has both a template argument list and a template parameter list. The compiler uses the partial specialization if its template argument list matches a subset of the template arguments of a template instantiation. The compiler will then generate a new definition from the partial specialization with the rest of the unmatched template arguments of the template instantiation.
You cannot partially specialize function templates.
The declaration_name is a name of a previously declared template. Note that you can forward-declare a partial specialization so that the declaration_body is optional.
#include <iostream>
using namespace std;
template<class T, class U, int I> struct X
{ void f() { cout << "Primary template" << endl; } };
template<class T, int I> struct X<T, T*, I>
{ void f() { cout << "Partial specialization 1" << endl;
} };
template<class T, class U, int I> struct X<T*, U, I>
{ void f() { cout << "Partial specialization 2" << endl;
} };
template<class T> struct X<int, T*, 10>
{ void f() { cout << "Partial specialization 3" << endl;
} };
template<class T, class U, int I> struct X<T, U*, I>
{ void f() { cout << "Partial specialization 4" << endl;
} };
int main() {
X<int, int, 10> a;
X<int, int*, 5> b;
X<int*, float, 10> c;
X<int, char*, 10> d;
X<float, int*, 10> e;
// X<int, int*, 10> f;
a.f(); b.f(); c.f(); d.f(); e.f();
}
Primary template
Partial specialization 1
Partial specialization 2
Partial specialization 3
Partial specialization 4
The compiler would not allow the declaration X<int, int*, 10> f because it can match template struct X<T, T*, I>, template struct X<int, T*, 10>, or template struct X<T, U*, I>, and none of these declarations are a better match than the others.
Each class template partial specialization is a separate template. You must provide definitions for each member of a class template partial specialization.
Primary templates do not have template argument lists; this list is implied in the template parameter list.
Template parameters specified in a primary template but not used in a partial specialization are omitted from the template parameter list of the partial specialization. The order of a partial specialization's argument list is the same as the order of the primary template's implied argument list.
template<int I, int J> class X { };
// Invalid partial specialization
template<int I> class X <I * 4, I + 3> { };
// Valid partial specialization
template <int I> class X <I, I> { };
template<class T, T i> class X { };
// Invalid partial specialization
template<class T> class X<T, 25> { };
A partial specialization's template argument list cannot be the same as the list implied by the primary template.
You cannot have default values in the template parameter list of a partial specialization.