Sun Studio 12 Update 1: C++ ユーザーズガイド

6.6 テンプレートの特殊化

次の twice の例のように、テンプレート引数を例外的に特定の形式で組み合わせると、パフォーマンスが大幅に改善されることがあります。あるいは、次の sort の例のように、テンプレート記述がある引数の組み合わせに対して適用できないこともあります。テンプレートの特殊化によって、実際のテンプレート引数の特定の組み合わせに対して代替実装を定義することが可能になります。テンプレートの特殊化はデフォルトのインスタンス化を無効にします。

6.6.1 テンプレートの特殊化宣言

前述のようなテンプレート引数の組み合わせを使用するには、その前に特殊化を宣言する必要があります。次の例は twicesort の特殊化された実装を宣言しています。


template <> unsigned twice<unsigned>( unsigned original );

template <> sort<char*>(Array<char*> store);

コンパイラがテンプレート引数を明確に確認できる場合には、次の例のようにテンプレート引数を省略することができます。たとえば、次のようにします。


template <> unsigned twice(unsigned original);

template <> sort(Array<char*> store);

6.6.2 テンプレートの特殊化定義

宣言するテンプレートの特殊化はすべて定義する必要があります。次の例は、前の節で宣言された関数を定義しています。


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 テンプレートの特殊化の使用とインスタンス化

特殊化されたテンプレートはほかのすべてのテンプレートと同様に使用され、インスタンス化されます。ただし、完全に特殊化されたテンプレートの定義はインスタンス化でもあります。

6.6.4 部分特殊化

前述の例では、テンプレートは完全に特殊化されています。つまり、このようなテンプレートは特定のテンプレート引数に対する実装を定義しています。テンプレートは部分的に特殊化することも可能です。これは、テンプレートパラメータの一部だけを指定する、または、1 つまたは複数のパラメータを特定のカテゴリの型に制限することを意味します。部分特殊化の結果、それ自身はまだテンプレートのままです。たとえば、次のコード例に、本来のテンプレートとそのテンプレートの完全特殊化を示します。


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

次のコード例に、本来のテンプレートの部分特殊化を示します。


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