以嵌套类为参数的友元模板声明

Friend template declaration with nested class as argument

本文关键字:友元 声明 参数 嵌套      更新时间:2023-10-16

C++常见问题解答提供了如何编写友元模板声明的指南。但是,当其中一个参数是模板类的嵌套结构时,我遇到了一个问题,例如:

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

写这篇文章的正确语法是什么?

实时演示

operator<<永远不能用作运算符,因为T只出现在非推导上下文中。出于同样的原因,编译器在试图准确地找出要匹配的函数模板的哪个专业化时,无法推导出模板参数。

还有一个小问题是,专门化命名了它无权访问的私有成员Node(编译器在弄清楚声明命名的是哪个专门化之前,无法弄清楚friend声明是否授予它这样的访问权限(。

通常的修复方法是将运算符定义为类模板定义中的内联非模板函数,或者将Node提取到自己的类模板中。