C++:用于operator <<的模板类中的friend函数

Vin*_*ent 5 c++ templates friend ostream

在.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
}
Run Code Online (Sandbox Code Playgroud)

非常感谢你 !

Luc*_*ton 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);
};
Run Code Online (Sandbox Code Playgroud)

您拥有的定义应与这些声明匹配.请注意,由于它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);
Run Code Online (Sandbox Code Playgroud)

您拥有的定义也应该匹配这样的声明(模板参数的名称与匹配的声明和定义无关).

为了完整起见,我将提到,当涉及到类模板的朋友时,另一种方法是在类模板定义中定义它.这定义了非模板友元函数,该函数对于每个特化都是唯一的.

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

不可能引用这些函数(例如&ns::operator<<,与其他选项不同,它们不起作用)并且它们仅通过ADL找到.