为什么不能在类中引用转发声明的朋友类?

时间:2018-08-27 18:12:42

标签: c++ friend

以下代码无法编译:

struct X {
  friend class Y;
  Y* ptr;
};

cppreference将情况描述为

  

...如果在朋友声明中使用的类的名称是   尚未声明,它是当场提前声明。

如果“地点”表示声明了朋友关系,则可以声明成员Y* ptr。为什么不编译?标准中哪里禁止这样做?

3 个答案:

答案 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