extern テンプレート(C++11)
BCC32 ではトランスレーション ユニットでインスタンス化されないテンプレートを定義できる extern テンプレートが使用できます。 extern テンプレートを使用すると、コンパイル時間が短縮し、コンパイル モジュールのサイズが小さくなります。 この機能は新しい C++11 標準の一部です。
明示的なインスタンス化と宣言
extern テンプレートでは、トランスレーション ユニットでインスタンス化しないテンプレートを宣言できます。
次のテンプレートを作成し、インスタンス化するコードで説明します。
template <class T> class MyClass { // ... various code } template class MyClass<int>; ... MyClass<int> myClass;
template class MyClass<int> の行は明示的なテンプレート定義で、コード ユニットでテンプレートが明示的にインスタンス化され、結果として対象ユニットでテンプレート用のコードが生成されます。 同様に、MyClass<int> myClass; 行はテンプレートを暗黙的にインスタンス化します。これもユニットにコードが生成されます。 これらのコード行のいずれかがユニットにある場合は、ユニットでテンプレートはインスタンス化されます。
ただし、ライブラリでこのテンプレートがすべてインスタンス化されることが必要で、実行可能ファイルでこれらのインスタンスを参照するとします。 コード ユニットでテンプレートがインスタンス化されない明示的なテンプレートを宣言する場合は、次のコードを使用します。
extern template class MyClass<int>;
テンプレートを参照できますが、コンパイラはこのトランスレーション ユニットにテンプレートに対するコードを生成しません。
extern テンプレートの使用方法
ここに extern テンプレートを使用するルールを示します。
- テンプレートのインスタンス化は対象のトランスレーション ユニットまたは別のトランスレーション ユニットでの明示的なテンプレート宣言が必要です。 これは extern の通常の使用方法と同様です。 参照対象のエンティティは必ずどこかに定義する必要があります。
- 明示的なテンプレート定義はユニットで 1 回だけ必要です。
- 明示的なテンプレート定義はトランスレーション ユニットに両方が存在する場合は明示的なテンプレート宣言に従う必要があります。
- 明示的なテンプレート宣言は明示的なテンプレートのインスタンス、オブジェクト、関数の名前のみに適用できます。 静的関数を参照できませんが、静的メンバ関数に適用できます。
- extern 指定子はクラス メンバやパラメータの宣言に使用できません。
- 明示的なテンプレート宣言はテンプレートが同じ特殊化でインスタンス化されていない場合にだけ、コードを生成しません。 次に例を示します:
template class MyClass<int>; ... extern template class MyClass<int>; // not allowed extern template class MyClass<float>; // OK