コンパイラは、テンプレートのostream <<演算子を作成しません
-
23-08-2019 - |
質問
私が持っていると頭の中で定義されたクラス、ます:
template <typename T> class MyClass
{
template <typename U> friend std::ostream& operator<<(std::ostream& output, const MyClass<U>& p);
public:
...
}
実装ファイルでは、私が持っています:
template <typename U> std::ostream& operator<<(std::ostream& output, const MyClass<U>& m)
{
output << "Some stuff";
return output;
}
どのすべてはかなりコーシャに見えます。しかし、私は試してみて、この演算子を使用する場合(つまりはstd :: coutの<<のMyClass())、私は、次のリンカエラーを取得します:
Undefined symbols: std::basic_ostream<char, std::char_traits<char> >& operator<< <InnerType>(std::basic_ostream<char, std::char_traits<char> >&, MyClass<InnerType> const&)
私は、任意の提案は、私が間違ってやっている?
のよう...コンパイラはautomagicially私のためにこれを生成していない驚いています解決
実装ファイルでは、私が持っています:
これは問題です。あなたは、ヘッダーと実装ファイル間のテンプレート定義を分割することはできません。テンプレートの性質のために、C ++コンパイラは、ここで凝り性です。それを動作させるために、ヘッダー内のすべてのコードを定義します。
実際には、ここでの問題は、C ++標準では、異なる単位間で共有されているかテンプレートの情報を定義していないため、すべてのテンプレートの定義が同じコンパイル単位内に存在しなければならないということです。リンク時にのないの、これらのユニットは、リンカーによって一緒にステッチされますが、ジェネリック医薬品は、(早い)、コンパイル時に解決されます。
理論的には、C ++標準では、これらのケースを処理するために、キーワード、export
を定義します。実際には、いいえコンパイラは(?一つの例外を除いて)これを実装していない、およびコスト/有用性のトレードオフが十分に良いとされていないため、これを変更する意図はない。
他のヒント
あまりにも多くのテンプレート - この作品ます:
#include <iostream>
using namespace std;
template <typename T> struct MyClass {
friend ostream & operator << ( ostream & os, MyClass<T> & c ) {
os << "MyClass\n";
return os;
}
};
int main() {
MyClass <int> c;
cout << c;
}
所属していません StackOverflow