暗黙のインスタンス化

C++テンプレートの特殊化が明示的にインスタンス化されない限り、 または明示的に特殊化されない限り、コンパイラーは、定義が必要とされる場合にのみ、 テンプレートの特殊化を生成します。 これは、暗黙のインスタンス化 と呼ばれます。

コンパイラーが、クラス・テンプレート特殊化のインスタンスを生成する必要があり、 テンプレートが宣言される場合、テンプレートも定義する必要があります。

例えば、クラスを指すポインターを宣言する場合、そのクラスの定義は、必要とされず、 そのクラスは、暗黙的にインスタンス作成されません。 次は、コンパイラーが、テンプレート・クラスのインスタンスを作成する例を示しています。

template<class T> class X {
   public:
    X* p;
    void f();
    void g();
};
 
X<int>* q;
X<int> r;
X<float>* s;
r.f();
s->g();
 

コンパイラーは、次のクラスおよび関数のインスタンス化を必要とします。

したがって、上記の例をコンパイルするには、 関数 X<T>::f() および X<T>::g() を定義する必要があります。 (コンパイラーは、オブジェクト r を作成する場合、 クラス X のデフォルトのコンストラクターを使用します。) コンパイラーは、次の定義のインスタンス化を必要としません。

コンパイラーが、ポインター型変換、またはメンバー型変換を指すポインターに関係する場合、 それはクラス・テンプレート特殊化のインスタンスを暗黙的に生成します。 次の例は、このことを示しています。

template<class T> class B { };
template<class T> class D : public B<T> { };
 
void g(D<double>* p, D<int>* q)
{
  B<double>* r = p;
  delete q;
}

代入 B<double>* r = p は、型 D<double>*pB<double>* の型に変換します。コンパイラーは、D<double> のインスタンスを生成する必要があります。コンパイラーは、q の削除を試みる際に、 D<int> のインスタンスを生成しなければなりません。

コンパイラーが、静的メンバーを含むクラス・テンプレートのインスタンスを暗黙的に生成する場合、 それらの静的メンバーのインスタンスは、暗黙的には生成されません。 コンパイラーは、静的メンバーの定義を必要とする場合のみ、 静的メンバーのインスタンスを生成します。 インスタンスを生成されたクラス・テンプレートは、どれも静的メンバーの自分用のコピーを所有しています。 次の例は、このことを示しています。

template<class T> class X {
public:
   static T v;
};
 
template<class T> T X<T>::v = 0;
 
X<char*> a;
X<float> b;
X<float> c;

オブジェクト a には、型 char* の静的メンバー変数 v があります。 オブジェクト b には、型 float の静的変数 v があります。 オブジェクト bc は、単一静的データ・メンバー v を共用します。

暗黙的にインスタンスを生成されたテンプレートは、 テンプレートを定義した場所と同じネーム・スペースにあります。

関数テンプレート、またはメンバー関数テンプレート特殊化が、 多重定義解決にかかわってくる場合、コンパイラーは、 特殊化の宣言のインスタンスを暗黙的に生成します。

関連参照

IBM Copyright 2003