4

インライン化せずに、テンプレートクラスで挿入(<<)および/または抽出(>>)演算子をオーバーロードするにはどうすればよいですか。フレンドクラスとして<<または>>演算子を使用したいと思います。行列クラスのインラインの例をインラインにする方法を知っています

friend ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
   ...
   // create the ostr
   return ostr;
}

しかし、templateclass定義の外にコードを入れたいのですが。

g ++は、関数名の後に<>を追加するように指示したので、追加しましたが、SOMETYPE型の行列をインスタンス化しようとすると、その型の抽出または挿入の方法がわからないというエラーが発生しました。

4

3 に答える 3

2

次のようなものを試してください:

template <typename T> class Matrix;
template <typename T> std::ostream& operator<<(std::ostream& ostr, const Matrix<T>& m);

template <Typename T>
class Matrix
{
    public:

        friend ostream& operator<< <T> (ostream& ostr, const Matrix<K>& inputMatrix);
};

// This must be in the same translation unit as the class definition!
template<typename T>
ostream& operator<<(ostream& ostr, const Matrix<T>& inputMatrix)
{
   // ...
   return ostr;
}

翻訳ユニットリファレンス

ascheplerとdribeasによるコメントに対処するために再編集されました。

于 2010-11-09T19:23:42.130 に答える
2

本当に演算子を外部で定義し、このテンプレートのインスタンス化とタイプが一致する演算子のインスタンス化のみと友達にしたい場合、正しい構文は次のとおりです。

template <typename T> class test; // forward declare template class
template <typename T>              // forward declare the templated operator
std::ostream& operator<<( std::ostream&, test<T> const & );

template <typename T>
class test {                      // define the template
   friend std::ostream& operator<< <T>( std::ostream&, test<T> const & ); // befriend
};
template <typename T>              // define the operator 
std::ostream& operator<<( std::ostream& o, test<T> const & ) {
   return o;
}

ほとんどの場合、定義をクラスから引き出すのは面倒な価値はありません。それでもヘッダーで定義を提供する必要があり、追加の作業が必要になることを考慮してください。

また、ルックアップに関してコンパイラーにはわずかな違いがあることに注意してください。関数がクラス定義内にインライン化されている場合、引数の1つが実際にテンプレートのタイプでない限り、コンパイラーはその関数を検出しないため、コンパイラーが行う必要のある可視性と作業量が効果的に減少します。 do(テンプレートoperator<<がクラスの外部で定義されている場合、コンパイラは、見つかったすべての場所でオーバーロード解決の候補としてそれを見つけますa << bが、2番目の引数がaでない場合はすべて破棄しますtest<T>(そして、一致できないすべてのエラーメッセージの候補としてのテンプレート演算子operator<<。これはすでに十分な長さのリストです)。

于 2010-11-09T20:46:30.050 に答える
1

クラス定義の外側のヘッダーにコードを配置します。または、.tccファイルに配置して、ヘッダーの下部に含めます。

于 2010-11-09T19:17:39.540 に答える