53

タイトル参照。テンプレートがあります。テンプレートの特定のインスタンスを強制的にインスタンス化したい。どうすればいいですか?

より具体的には、抽象テンプレート クラスを強制的にインスタンス化できますか?


同じ質問があるので詳しく説明します。私の場合、ライブラリを構築しています。テンプレートの実装の一部は大きく、多くのものを含んでいますが、いくつかのタイプに対してのみ生成されます。それらをライブラリでコンパイルし、すべてのメソッドをエクスポートしたいのですが、どこにでもコードを含むヘッダーを含めたくありません。

すなわち:

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 および Intel コンパイラ用のライブラリを構築しています。

4

6 に答える 6

60

汎用テンプレートを強制的にインスタンス化することはできません。コンパイラは、型が完全にわかっている場合にのみコードを生成できます。

インスタンス化を強制するには、すべての型を明示的に指定します。

template class std::vector<int>;

Comeausテンプレートの FAQでは、関連する問題について詳しく説明しています。

于 2010-01-28T03:11:48.117 に答える
58

また、明示的なインスタンス化を試すこともできます。

template class vector<int>;                    // class
template int& vector<int>::operator[](int);    // member
template int convert<int,double>(double);      // function
于 2010-01-28T15:50:13.460 に答える
1

必要なパラメーターを指定したテンプレートを使用して、インスタンス化を強制できます。たとえば、必要なすべてのメソッドを使用して関数を定義できます。

void force_int_instance() {
  Abstract<int> *a;
  a->some_method();
  a->some_other_method(1, 2, 3);
}

その関数を実際にどこでも呼び出す必要はないので、ポインタが初期化されていなくても問題ありません。ただし、コンパイラは、関数が別のオブジェクト ファイルから呼び出される可能性があると想定する必要があるため、テンプレートをインスタンス化する必要があります。

于 2010-01-28T03:31:08.520 に答える
0

私があなたの質問を正しく理解していれば、テンプレート クラスがあり、特定の型で使用するコードをコンパイラに強制的に生成させたいと考えています。たとえば、 std::vector<int> のコードがプログラムに存在することを確認したい場合があります。

これを確実にする最善の方法は、クラスのインスタンスを単純に構築することです。

void EnsureInstantiation()
{
    std::vector<int> intvector;
    std::vector<boo> boolvector;
    /// etc.
}

秘訣は、コード内のどこでも、EnsureInstantiation を呼び出す必要さえないことです。静的でないことを確認してください。そうしないと、コンパイラ最適化する可能性があります。

于 2010-01-28T03:27:12.527 に答える
-3

私はあなたが言ったことではなく、あなたが意味したと思うことに答えるつもりです。

問題は2つのうちの1つだと思います。1つ目は、テンプレートファイル自体をコンパイルするときにコンパイルされないコードがテンプレートに含まれていることです。これは非常に煩わしい場合があります。これは、コンパイラの設定で修正できます。

もう1つは、特定のタイプに特別な何かを用意したいということです。おそらくそれをデバッグするためです。これは明示的なインスタンス化と呼ばれますが、実際には何もインスタンス化せず、その時点以降に常に定義されていることを確認するだけです。

http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/topic/com.ibm.vacpp6m.doc/language/ref/clrc16explicit_instantiation.htm

于 2010-01-28T07:09:12.233 に答える
-3

抽象クラスはインスタンス化できません。おそらく次の行に沿って何かをしたいでしょう:

Abstract *a = new Implementation(...);

テンプレートのインスタンス化を強制するには、テンプレート パラメーターを指定して template を呼び出します。

std::max<int>(...);
std::pair<int, string>(...);
于 2010-01-28T03:10:55.983 に答える