コンパイラーに、テンプレートから定義をいつ生成するのかを明示的に指示できます。
これは、明示的インスタンス化 と呼ばれます。
構文 - 明示的インスタンス化宣言 >>-template--template_declaration------------------------------><
下記は、明示的インスタンス化の例です。
template<class T> class Array { void mf(); }; template class Array<char>; // explicit instantiation template void Array<int>::mf(); // explicit instantiation template<class T> void sort(Array<T>& v) { } template void sort(Array<char>&); // explicit instantiation namespace N { template<class T> void f(T&) { } } template void N::f<int>(int&); // The explicit instantiation is in namespace N. int* p = 0; template<class T> T g(T = &p); template char g(char); // explicit instantiation template <class T> class X { private: T v(T arg) { return arg; }; }; template int X<int>::v(int); // explicit instantiation template<class T> T g(T val) { return val;} template<class T> void Array<T>::mf() { }
テンプレート宣言は、テンプレートの明示的インスタンス化のインスタンス化ポイントのスコープ内になければなりません。 テンプレート特殊化の明示的インスタンス化は、テンプレートを定義した場所と同じネーム・スペースにあります。
アクセス検査規則は、明示的インスタンス化には適用されません。 明示的インスタンス化の宣言に含まれるテンプレート引き数および名前は、private 型、またはオブジェクトになります。 上記の例では、コンパイラーは、 メンバー関数が private で宣言されていても、明示的インスタンス生成である template int X<int>::v(int) を許可します。
テンプレートのインスタンスを明示的に生成する場合、コンパイラーは、デフォルトの引き数を使用しません。 上記の例では、コンパイラーは、デフォルトの引き数が型 int のアドレスであっても、明示的インスタンス化 template char g(char) を許可します。
extern 修飾テンプレート宣言は、クラスまたは関数をインスタンス化しません。 クラスと関数の両方において、 extern テンプレートのインスタンス化は、先行するコードでまだ extern テンプレートのインスタンス化でトリガーされていなければ、テンプレートのパーツをインスタンス化しません。 クラスの場合、メンバー (静的と非静的の両方) はインスタンス化されません。 クラス自体は、そのクラスをマップする必要がある場合はインスタンス化されます。 関数の場合、プロトタイプはインスタンス化されますが、テンプレート関数の本体はインスタンス化されません。
次の例では、extern を使用したテンプレートのインスタンス化を示します。
template<class T>class C { static int i; void f(T) { } }; template<class U>int C<U>::i = 0; extern template C<int>; // extern explicit template instantiation C<int>c; // does not cause instantiation of C<int>::i // or C<int>::f(int) in this file, // but the class is instantiated for mapping C<char>d; // normal instantiations
template<class C> C foo(C c) { return c; } extern template int foo<int>(int); // extern explicit template instantiation int i = foo(1); // does not cause instantiation of the body of foo<int>
関連参照