2009-06-18 14 views
0

通常、テンプレート化されたクラスでは、.hppファイルとテンプレート化された実装コードの宣言を.t.hppファイルに含めます。そのオブジェクトコードのライブラリに入れますテンプレート演算子<<明示的なインスタンス化とヘッダー

template class MyClass<AnotherClass>; 

:私は明示的.cppファイル内のクラスをインスタンス化します。

template<class T> 
std::ostream& operator<<(std::ostream& os, const MyClass<T>& c) 
{ 
    os << "Hello, I am being output."; 
    return os; 
} 

私は右のシンボルと言っリンカエラーを取得:

問題は、私は.hppファイルで宣言として.t.hppファイルで定義されている、operator<<でオブジェクトを印刷しようとするということです定義されていません。

これは、このテンプレート化された関数が、クラスが次のときに明示的にインスタンス化されていないためです。クラスにoperator<<を使用する場合、またはテンプレート化された関数コードを.hppファイルに移動する場合はいつでも、.t.hppファイルを含める以外の方法がありますか?関数コードを明示的にインスタンス化できますか?

答えて

2

明示的T = intに特化をインスタンス化するには、関数テンプレート

template std::ostream& operator<<(std::ostream&, const MyClass<int>&); 

をインスタンス化することができます。すべてのテンプレート引数が推測できる場合は、テンプレートの引数ブラケットを省略することができます(この場合は、タイプMyClass<int>から入力できます。たとえば、テンプレートパラメータが関数パラメータタイプでは発生しないため、明示的にそれは

template<typename T> void f() { } 
template void f<int>(); 
+0

+1。私はちょうど推論されていないケースを追加して、あなたがすでにそれを含むように更新したのを見て... Grr! :) –

+0

ありがとう!これは私が必要としたものです。テンプレート化された関数を明示的にインスタンス化することはできませんでした。 –

2

litb's solutionを参照してください指定

をあなたの特定のケースでは、それはあなたが明示的にそれらを与えることができなかった場合、パラメータのすべてのテンプレート引数を推定し、型を返すことができますが、コンパイラ:

template std::ostream& operator<< <T>(std::ostream&, const MyClass<T>&); 

これは、テンプレートの引数を推測できる場合でも可能です。

質問することがあります:明示的にすべてをインスタンス化する理由がありますか?あなたは自分のためにかなりの仕事をしています。テンプレートのソースコードをどこにも含めないようにして、コンパイル時間を節約できますが、開発者にとっては価値がありますか?

+0

私はまったく同じ質問をしています。ほとんどの場合、IMHOは開発時間>実行時間>コンパイル時間です。 –

+0

これは科学計算コード用です。多くのコードがディメンションにテンプレート化されています。つまり、テンプレートパラメータは、1-D問題などを実行しているかどうかによって、1、2、3のいずれかの符号なし整数です。 実行時間は非常に重要です。余分な開発時間(私は実質的にテンプレートパラメータを変更したり、クラスを追加したりする必要がないため)は余分なコンパイル時間の価値があります。最後のテンプレートコードを静的さまざまなフロントエンド、ユニットテストなどにリンクされたライブラリ –

+0

@Seth:明示的にインスタンス化されたコードの実行時間は、暗黙的にインスタンス化されたコードよりも優れていることはなく、コンパイラーがインライン化を実行できないため、悪化することがあります。これはタイトなループで大きな違いを生み出すことができます。 (ただし、行列乗算のような数値プリミティブには、既存のCPUチューニングライブラリを使用するのが一般的ですが、通常は非常に高速です)。 –

関連する問題