5

.cpp ファイルで(std::ostream& operator<< の) テンプレート クラスのフレンド関数を宣言する正しい方法は何ですか?

私の現在の実装は機能しません:

// MyTest.h
template<class T, unsigned int TSIZE> class MyTest
{
    inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs);
};

// MyTest.cpp
template<class T, unsigned int TSIZE> inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs)
{
    // IMPLEMENTATION
}

どうもありがとうございました !

4

2 に答える 2

8

operator<< <T, TSIZE>テンプレートの特殊化であるあなたのように参照するには、プライマリテンプレートの宣言が表示されている必要があります。次に、パラメータとして表示されるためoperator<<、の宣言が必要です。MyTest

// Declare MyTest because operator<< needs it
template<class T, unsigned int TSIZE> class MyTest;

// Declare primary template
template<class T, unsigned int TSIZE>
inline std::ostream& operator<<(std::ostream& lhs, const MyText<T, TSIZE>& rhs);

template<class T, unsigned int TSIZE> class MyTest
{
    // Specialization MyTest<T, TSIZE> only declares
    // specialization operator<< <T, TSIZE> as friend
    // Note that you can just use '<>' to designate the specialization,
    // template parameters are deduced from the argument list in this case
    inline friend std::ostream& operator<< <> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs);
};

あなたが持っている定義はそれらの宣言と一致する必要があります。operator<<テンプレートであるため、その定義はすべての可能性でヘッダーに含まれている必要があることに注意してください。

これらすべてのプリエンプティブ宣言を作成する際に必要な作業が少なくて済む代替手段は、を必要とするMyTest<T, TSIZE>特殊化だけでなく、テンプレート全体をフレンドとして宣言することMyTest<T, TSIZE>です。

// in MyTest definition
template<typename U, unsigned USIZE>
inline friend std::ostream& operator<<(std::ostream& lhs, const MyTest<U, USIZE>& rhs);

使用する定義もそのような宣言と一致する必要があります(テンプレートパラメーターの名前は、宣言と定義の一致とは関係ありません)。

完全を期すために、クラステンプレートの友達になると、別の方法はクラステンプレート定義で定義することです。これは、各専門分野に固有の非テンプレートフレンド関数を定義します。

// in MyTest definition
friend std::ostream& operator<<(std::ostream& lhs, MyTest const& rhs)
{ /* implementation */ }

このような関数を参照することは不可能であり(たとえば&ns::operator<<、他のオプションとは異なり、機能しません)、ADLを介してのみ検出されます。

于 2012-07-30T05:23:40.910 に答える
0

元の投稿が何を望んでいたかは完全には明らかではありません。私はそれが次のことを望んでいたと仮定します:

// Some template class.
template<class T, unsigned int TSIZE> class MyTest { };

// Some template function.
template<class T, unsigned int TSIZE> std::ostream& operator<< (std::ostream &lhs, const MyTest<T, TSIZE> &rhs)
{
    // IMPLEMENTATION
}

この関数は の保護されたオブジェクトにアクセスする必要があるため、このテンプレート関数をクラスのフレンドとして宣言する必要がありますMy test。これは、次の定義で実現できます。

template<class T, unsigned int TSIZE> class MyTest
{
    template<class T1, unsigned int TSIZE1> 
    friend std::ostream& operator<< (std::ostream &lhs, const MyTest<T1, TSIZE1> &rhs);
};

friendこれは関連のないテンプレート関数であり、現在のテンプレート クラスに属していないため、宣言の前にテンプレート ヘッダーが必要です。

于 2012-07-30T05:40:39.833 に答える