C++ FAQ提供了如何编写朋友模板声明的指南。但是当参数之一是模板类的嵌套结构时,我遇到了一个问题,例如:
template<typename T>
class MyClass;
template<typename T> QDataStream &operator<<(QDataStream &stream, const typename MyClass<T>::Node &node);
这两个版本都不起作用:
template<typename T>
class MyClass
{
private:
struct Node {};
friend QDataStream &operator<< <>(QDataStream &stream, const Node &node);
friend QDataStream &operator<< <>(QDataStream &stream, const MyClass::Node &node);
friend QDataStream &operator<< <>(QDataStream &stream, const MyClass::Node &node);
friend QDataStream &operator<< <>(QDataStream &stream, const typename MyClass<T>::Node &node);
friend QDataStream &operator<< <>(QDataStream &stream, const typename MyClass::Node &node);
};
template<typename T>
QDataStream &operator<<(QDataStream &stream, const typename MyClass<T>::Node &node)
{
return stream;
}
(MSVC 2017)给出的错误是:
error: C2672: '<<': no matching overloaded function found
写这个的正确语法是什么?
答案 0 :(得分:2)
此operator<<
永远不能用作运算符,因为T
仅出现在非推论上下文中。出于同样的原因,当试图准确找出要匹配的功能模板的哪种专业性时,编译器无法推导template参数。
还有一个小问题,即专业化将其无权访问的私有成员命名为Node
(编译器无法确定friend
声明是否授予了这样的访问权,直到找到它声明指定哪个专业)。
通常的解决方法是将运算符定义为类模板定义中的内联非模板函数,或者将Node
提取到其自己的类模板中。