タイトルを参照してください。テンプレートがあります。テンプレートの特定のインスタンスを強制的にインスタンス化したい。どうすればよいですか?
具体的には、抽象テンプレートクラスを強制的にインスタンス化できますか?
同じ質問があるので、詳しく説明します。私の場合、ライブラリを構築しています。いくつかのテンプレートの実装は大きく、多くのものが含まれていますが、いくつかのタイプに対してのみ生成されます。ライブラリでそれらをコンパイルし、すべてのメソッドをエクスポートしますが、どこにでもコードを含むヘッダーは含めません。
すなわち:
template<class T>
OS_EXPORT_DECL class MyTmpl
{
T *item1;
public:
inline T *simpleGetT() { return(item1); } /* small inline code in here */ }
T *doSomeReallyBigMergeStuff(T *b); // note only declaration here
};
// *** implementation source file only seen inside library
template<class T>
MyTmpl<T>::doSomeReallyBigMergeStuff(T *b)
{
... a really big method, but don't want to duplicate it,
so it is a template ...
}
もちろん、ライブラリ内のすべてのメソッドを参照してそれらを強制的にコンパイルおよびエクスポートすることもできますが、アイテムの引数のフォーマットやそれらを呼び出すコードなど、不要なコードをライブラリに追加したくない場合があります。
?????具体的には、MSCおよびGCCコンパイラとインテルコンパイラのいくつかのバージョンのライブラリを構築しています。
汎用テンプレートを強制的にインスタンス化することはできません。コンパイラーは、タイプが完全にわかっている場合にのみコードを生成できます。
インスタンス化を強制するには、すべてのタイプを明示的に指定します。
template class std::vector<int>;
コモー テンプレートFAQ は、関連する問題をある程度詳しくカバーしています。
あなたも試すことができるのは明示的なインスタンス化です:
template class vector<int>; // class
template int& vector<int>::operator[](int); // member
template int convert<int,double>(double); // function
目的のパラメーターを指定したテンプレートを使用して、インスタンス化を強制できます。たとえば、必要なすべてのメソッドを使用して関数を定義できます。
void force_int_instance() {
Abstract<int> *a;
a->some_method();
a->some_other_method(1, 2, 3);
}
実際にその関数をどこかで呼び出す必要はないので、ポインターが初期化されていなくても問題ありません。ただし、コンパイラは、関数が別のオブジェクトファイルから呼び出される可能性があると想定する必要があるため、テンプレートをインスタンス化する必要があります。
私があなたの質問を正しく理解している場合、テンプレートクラスがあり、特定のタイプで使用するコードをコンパイラーに強制的に生成する必要があります。たとえば、プログラムにstd :: vector <int>のコードが存在することを確認したい場合があります。
これを確実にする最良の方法は、クラスのインスタンスを単に構成することです。
void EnsureInstantiation()
{
std::vector<int> intvector;
std::vector<boo> boolvector;
/// etc.
}
秘訣は、コードのどこかでEnsureInstantiationを呼び出す必要さえないということです。静的でないことを確認してください。そうでない場合はコンパイラmayで最適化してください。