1

これを機能させるのに苦労しています

file: myclass.hpp

Class MyClass {
public:
  template <class T>    
  MyClass &operator<<(const T &val);
};


file: myclass.cpp

template <class T>
MyClass &MyClass::operator<<(const T &val) {
   ...  
}

これを問題なくオブジェクトにコンパイルできますが、他の関数がそれを呼び出そうとすると、このエラーが発生します (<< が使用されるたびに)。

myclass.cpp: undefined reference to `MyClass& MyClass::operator<< <int>(int const&)'

私は何を間違っていますか?

4

3 に答える 3

8

テンプレートのインスタンスを別々のコンパイル ユニットで定義する場合 (通常はそうです)、別の cpp でテンプレート メソッドを定義することはできません。すべてのテンプレート メソッドは、そのテンプレート クラスを使用するコンパイル ユニットをコンパイルするときに、コンパイラに表示される必要があります。したがって、cpps 全体でテンプレートを使用する場合は、テンプレートをヘッダーで定義する必要があります。テンプレートは、それ自体ではなくクラスを生成する実際の方法です。したがって、コンパイラが見たとき

YourClass<int>

という型を生成するには、コンパイル時にYourClass テンプレート全体を確認する必要があります。

YourClass<int>

およびそのすべてのメソッドには、say とは完全に別のメソッドがあります。

YourClass<float>

つまり、すべての C++ ソース コードを表示する必要があります。テンプレートのこれら 2 つの使用が別々の cpp でインスタンス化されている場合、コンパイラが両方を生成できる唯一の方法は、テンプレートを 1 つのヘッダーで完全に定義することです。

詳細については、こちらの回答を参照してください。

この回答を大幅に改善した有益なコメントをありがとう

于 2009-06-10T16:49:46.757 に答える
4

演算子の定義を の.hpp代わりに に入れ.cppます。コンパイラは、テンプレートが新しい型のためにインスタンス化されるときに、テンプレートの完全な定義を認識できる必要があります。これにより、この特殊化のコードを生成できます。

C++ FAQ Liteには、この種のテンプレート関連のリンカ エラーとさまざまな解決策に関するいくつかの質問と回答もあります。

于 2009-06-10T16:49:34.620 に答える
2

テンプレートは、cpp ファイルではなくヘッダー ファイルで定義する必要があります。実際の実装は、使用時に必要に応じて各コンパイル単位で作成されます。その点ではマクロのようなものです。

于 2009-06-10T16:52:35.330 に答える