There may be performance advantages to treating some combinations of template arguments as a special case, as in the following examples for twice. Alternatively, a template description might fail to work for a set of its possible arguments, as in the following examples for sort. Template specialization allows you to define alternative implementations for a given combination of actual template arguments. The template specialization overrides the default instantiation.
You must declare a specialization before any use of that combination of template arguments. The following examples declare specialized implementations of twice and sort.
template <> unsigned twice<unsigned>( unsigned original );
template <> sort<char*>( Array<char*> store );
You can omit the template arguments if the compiler can unambiguously determine them. For example:
template <> unsigned twice( unsigned original );
template <> sort( Array<char*> store );
You must define all template specializations that you declare. The following examples define the functions declared in the preceding section.
template <> unsigned twice<unsigned>( unsigned original )
{ return original << 1; }
#include <string.h>
template <> void sort<char*>( Array<char*> store )
{ int num_elems = store.GetSize( );
for ( int i = 0; i < num_elems-1; i++ )
for ( int j = i+1; j < num_elems; j++ )
if ( strcmp( store[j-1], store[j] ) > 0 )
{ char *temp = store[j];
store[j] = store[j-1];
store[j-1] = temp; } }
A specialization is used and instantiated just as any other template, except that the definition of a completely specialized template is also an instantiation.