ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
Oracle Solaris Studio 12.3: C++ ユーザーズガイド Oracle Solaris Studio 12.3 Information Library (日本語) |
6.3.2.3 テンプレートクラス関数メンバーの明示的インスタンス化
6.3.2.4 テンプレートクラスの静的データメンバーの明示的インスタンス化
この節の twice の例のように、テンプレート引数を例外的に特定の形式で組み合わせると、パフォーマンスがいくらか改善されることがあります。あるいは、この節の sort の例のように、ある引数の組み合わせに対してはテンプレート記述を適用できないこともあります。テンプレートの特殊化によって、実際のテンプレート引数の特定の組み合わせに対して代替実装を定義することが可能になります。テンプレートの特殊化はデフォルトのインスタンス化を無効にします。
前述のようなテンプレート引数の組み合わせを使用するには、その前に特殊化を宣言する必要があります。次の例は twice と sort の特殊化された実装を宣言しています。
template <> unsigned twice<unsigned>( unsigned original );
template <> sort<char*>(Array<char*> store);
コンパイラがテンプレート引数を明確に確認できる場合には、次の例のようにテンプレート引数を省略することができます。例:
template <> unsigned twice(unsigned original);
template <> sort(Array<char*> store);
宣言するテンプレートの特殊化はすべて定義する必要があります。次の例は、前の節で宣言された関数を定義しています。
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;}}
特殊化されたテンプレートはほかのすべてのテンプレートと同様に使用され、インスタンス化されます。ただし、完全に特殊化されたテンプレートの定義はインスタンス化でもあります。
前述の例では、テンプレートは完全に特殊化されています。つまり、このようなテンプレートは特定のテンプレート引数に対する実装を定義しています。テンプレートは部分的に特殊化することも可能です。これは、テンプレートパラメータの一部だけを指定する、または、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
例 1 は、最初のテンプレートパラメータが int 型である特殊なテンプレート定義です。
例 2 は、最初のテンプレートパラメータが任意のポインタ型である、特殊なテンプレート定義です。
例 3 は、最初のテンプレートパラメータが任意の型のポインタへのポインタであり、2 番目のテンプレートパラメータが char 型である、特殊なテンプレート定義です。