c++に関するよくある質問35.16
http://www.parashift.com/c++-faq-lite/template-friends.html
#include <iostream>
template<typename T>
class Foo {
public:
Foo(T const& value = T());
friend Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs);
friend std::ostream& operator<< (std::ostream& o, const Foo<T>& x);
private:
T value_;
};
autorは主張します:
'この障害は、コンパイラがクラス定義でフレンドラインが適切に並んでいることを確認したときに発生します。その時点では、フレンド関数自体がテンプレートであるかどうかはまだわかりません(なぜですか?クラステンプレートのメンバー関数はデフォルトで関数テンプレートではありませんか?) ; これらは次のような非テンプレートであると想定しています。
Foo<int> operator+ (const Foo<int>& lhs, const Foo<int>& rhs)
{ ... }
std::ostream& operator<< (std::ostream& o, const Foo<int>& x)
{ ... }
上記の非テンプレートはなぜですか?これらのテンプレートはintを介してインスタンス化されていませんか?
'operator+またはoperator<<関数を呼び出すと、この仮定により、コンパイラは非テンプレート関数の呼び出しを生成しますが、これらの非テンプレート関数を実際に定義したことがないため、リンカは「未定義の外部」エラーを返します。 。'
実際、コンパイラーに上記を関数テンプレートとして認識させるには、プログラマーは以下のように明示的にこれを行う必要があります。
template<typename T> class Foo; // pre-declare the template class itself
template<typename T> Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs);
template<typename T> std::ostream& operator<< (std::ostream& o, const Foo<T>& x);
誰か説明してもらえますか?これは非常に厄介で、コンパイラがTを「int」に置き換えてClass Fooのインスタンスをインスタンス化し、それを1日と呼んでいない理由がわかりません。
ありがとう。