Go to main content
Oracle® Developer Studio 12.6: C++ User's Guide

Exit Print View

Updated: July 2017
 
 

6.6 Template Specialization

Treating some combinations of template arguments as a special case might provide some performance gains, as in the examples for twice in this section. Alternatively, a template description might fail to work for a set of its possible arguments, as in the examples for sort in this section. Template specialization allows you to define alternative implementations for a given combination of actual template arguments. The template specialization overrides the default instantiation.

6.6.1 Template Specialization Declaration

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);

6.6.2 Template Specialization Definition

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;}}

6.6.3 Template Specialization Use and Instantiation

A specialization is used and instantiated just as any other template, except that the definition of a completely specialized template is also an instantiation.

6.6.4 Partial Specialization

In the previous examples, the templates are fully specialized. That is, they define an implementation for specific template arguments. A template can also be partially specialized, meaning that only some of the template parameters are specified, or that one or more parameters are limited to certain categories of type. The resulting partial specialization is itself still a template. For example, the following code sample shows a primary template and a full specialization of that template.

template<class T, class U> class A {...}; //primary template
template<> class A<int, double> {...};    //specialization

The following code shows examples of partial specialization of the primary template.

template<class U> class A<int> {...};          // Example 1
template<class T, class U> class A<T*> {...};  // Example 2
template<class T> class A<T**, char> {...};    // Example 3
  • Example 1 provides a special template definition for cases when the first template parameter is type int.

  • Example 2 provides a special template definition for cases when the first template parameter is any pointer type.

  • Example 3 provides a special template definition for cases when the first template parameter is pointer-to-pointer of any type, and the second template parameter is type char.