以下代码无法编译:
struct X {
friend class Y;
Y* ptr;
};
cppreference将情况描述为
...如果在朋友声明中使用的类的名称是 尚未声明,它是当场提前声明。
如果“地点”表示声明了朋友关系,则可以声明成员Y* ptr
。为什么不编译?标准中哪里禁止这样做?
答案 0 :(得分:29)
这是网站上的错误。它违反了标准,该标准说友谊声明不能替代正向声明:
7.3.1.2.3在命名空间中首先声明的每个名称都是该命名空间的成员。如果非本地类中的某个好友声明首先声明了一个类,函数,类模板或函数模板,则该好友是最内层的命名空间的成员。朋友声明本身不会使名称对不合格查询或合格查询可见。
关于名称不合格或不合格查询不可见的部分,基本上意味着该名称的行为不像正向声明。
答案 1 :(得分:2)
除了@dasblinkenlight的答案外,3.3.2 Point of declaration lit. 10中的注释还明确指出,朋友声明不会引入(因此也不会“转发声明”)类名:
10 [注意:朋友声明引用的函数或类是 最接近的封闭名称空间的成员,但不引入 新名称添加到该名称空间([namespace.memdef])。
答案 2 :(得分:0)
解决此代码的一种方法是简单地add class
keyword:
struct X {
friend class Y;
class Y* ptr;
};
如果class Y
在全局范围内,它将在全局范围内转发声明X
。