声明模板类的友元函数(对于.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
}
非常感谢!
答案 0 :(得分: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找到它们。
答案 1 :(得分: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
声明前需要模板标头,因为这是一个不相关的模板函数,不属于当前模板类。