2010-11-25 15 views
1

私はcppファイル内にある必要があるテンプレートクラス定義を持っています。私は.cppファイルからテンプレートをインスタンス化テンプレートリンクの問題C++

// File "foo.cpp" 
#include <iostream> 
#include "foo.h" 

template<typename T> void foo() 
{ 
    std::cout << "Here I am!\n"; 
} 

template void foo<int>(); 

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13から採用し、私はこのような何かをしました。しかし、私はfoo(string)などのような異なる型が必要で、私はそれを一度しかインスタンス化できないことに気付きました。どうすれば修正できますか?

ありがとうございました。

+0

'template void foo ()'という文を追加すると、どのようなエラーメッセージが表示されますか? – lijie

答えて

4

それを使用foo.cppで

template <typename T> void foo() 
{ 
    std::cout << "Here I am! << std::endl; 
} 

定義を追加します。

template void foo<int>(); 
template void foo<double>(); 
template void foo<std::string>(); 

これは、多くのライブラリが任意のインスタンス化は、ヘッダを含む任意のcppファイルに利用できるようにすることができるように、ヘッダファイルにテンプレート関数の実装を提供する傾向がある理由である、やや面倒です。

+0

ライブラリにヘッダファイルの実装が含まれている理由はありません。ライブラリでテンプレートをインスタンス化しようとしている_know_タイプがある場合は、インスタンス化を別々に行うのが良いケースです。しかし、ほとんどのテンプレートライブラリは、それらをインスタンス化するためにどのような型が使用されるかを知らないため、ヘッダファイルに実装を提供する必要があります。 – lijie

+0

もちろんです。タイプのセットが多少固定されていても、新しいタイプが導入されるたびに、テンプレート関数のすべての実装ファイルを編集する必要があります。それは確かにコードの局所性に違反します。 –

0

テンプレートの特殊化は、ヘッダーファイル内の別の翻訳単位(.cppファイル)とテンプレート(汎用)定義にする必要があります。がfoo.hで はあなたが必要とするタイプごとにfooをインスタンス化することができるはず

foo <int>() 
foo <std::string>(); 
+1

インスタンス化ではなく、特殊化を本当に意味しますか?いくつかのコードがテンプレートをインスタンス化し、他の翻訳単位に対応する特殊化があることがわからない場合は、ODRに違反し、おそらくリンカーエラーや非常に興味深い動作につながるでしょうか? –

+0

私は1秒かかりました(私はそれを逆に言ったでしょう)が、クリスチャン・クロイツィヒは「専門化」を「インスタンス化」に置き換えることを提案しています。テンプレートを特殊化するには、特定のタイプの組み合わせ( 'vector '(残念なことに)のような)に対して特殊な動作を指定することです。 –