使用嵌套类作为参数的朋友模板声明

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用嵌套类作为参数的朋友模板声明相关的知识,希望对你有一定的参考价值。

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

写这个的正确语法是什么?

LIVE DEMO

答案

这个operator<<永远不能用作运算符,因为T只出现在非推导的上下文中。出于同样的原因,编译器在尝试确定您要尝试匹配哪个函数模板的确切特征时,无法推断出模板参数。

还有一个小问题,专门化命名私有成员Node它无法访问(编译器无法弄清楚friend声明授予它这样的访问权限,直到它确定声明命名的专业化)。

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

以上是关于使用嵌套类作为参数的朋友模板声明的主要内容,如果未能解决你的问题,请参考以下文章

在不知道其模板参数的情况下将类模板声明为朋友的最佳方法

gcc 编译错误:模板类表中嵌套类 A ​​的成员在嵌套朋友类中不可见。为啥?

声明嵌套类模板的静态对象

azure arm模板嵌套数组作为参数

使用 Django 模板作为片段

具有嵌套类声明的类模板 (C++)