Specialisation and partial specialisation
The ARM said that if you provided a specialisation - a definition of a template for a specific set of arguments - it would be used in place of the generated definition. ISO C++ requires that specialisations are declared before use so that the compiler knows, when it sees the use of the template, whether or not it needs to generate a definition or use a specialisation: template<typename T>
class List
{
// ...
};
template<> class List<int>;
// declare specialisation for T==int
List<double> ld;
// compiler knows this is generated version
List<int> li;
// compiler knows this is specialised version
Requiring template<> to introduce the declaration of a specialisation was a change introduced in Monterey in July '95. This makes all types of specialisation look similar - they all begin with template.
Template classes can now also be partially specified. A partial specialisation provides a more restrictive match to a given template:
template<typename T, typename U>
class Associate // #1: primary template
{
// ...
};
template<typename T>
class Associate<T*, T*>;
// #2: matches use with pair of
// identical pointers
template<typename T, typename U, typename V>
class Associate<T U::*, V>;
// #3: matches use with first arg
// pointer to member
Associate<char*, char*> app;
// uses partial specialisation #2
typedef double complex::* coord;
Associate<coord, double> apmd;
// uses partial specialisation #3
Associate<char*, int*> ap1p2;
// uses primary template #1
// (different pointers>
See also The Casting Vote: Austin - March '95. Note that you cannot partially specialise template functions, however similar result can sometimes be achieved with template function overloading.