【问题标题】:friend declaration not forward declaring朋友声明不转发声明
【发布时间】:2013-01-01 22:49:44
【问题描述】:

我的理解是,如果使用 class 说明符,friend 声明也可以用作类的前向声明,如下例所示:

class A
{
    friend class B;
    B* b;
};

class B {};

int main() {}

但是,g++(4.6.3 和 4.7.0)给了我以下错误(g++-4.7 应该支持extended friend declarations),这是没有前向声明的预期:

main.cpp:6:2: 错误:‘B’没有命名类型

为了确认我对 friend class B; 应该作为前向声明的期望,我找到了 this answerthis answer,但两者都不是决定性的(或者我至少无法从它们中得出很多结论)所以我试图查阅 c++11 标准并找到了这个例子:

class X2 {
    friend Ct; // OK: class C is a friend
    friend D; // error: no type-name D in scope
    friend class D; // OK: elaborated-type-specifier declares new class
}

根据我对第三个声明的阅读,我的friend class B 应该是一个声明一个新类的详细类型说明符

我刚刚开始理解官方标准措辞,所以我一定遗漏了一些东西。我误会了什么?

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    看看 11.3 第 11 段:

    对于友元类声明,如果没有前面的声明,则指定的类属于最内层的封闭非类作用域,但如果随后被引用,则直到匹配的声明才通过名称查找找到其名称在最里面的非类范围内提供。

    例子:

    class X;
    void a();
    void f() {
      class Y;
      extern void b();
      class A {
      friend class X;  // OK, but X is a local class, not ::X
      friend class Y;  // OK
      friend class Z;  // OK, introduces local class Z.
      friend void a(); // error, ::a is not considered
      friend void b(); // OK
      friend void c(); // error
      };
      X *px;           // OK, but ::X is found
      Z *pz;           // error, no Z is found
    }
    

    【讨论】:

      【解决方案2】:

      您的friend class B; 声明确实用作前向声明,但在提供匹配声明之前,无法通过名称查找找到此类声明。

      [class.friend]/11

      如果友元声明出现在本地类 (9.8) 中并且指定的名称是非限定名称,则在不考虑最内层非类范围之外的范围的情况下查找先前声明。对于友元函数声明,如果没有事先声明,则程序是非良构的。对于友元类声明,如果前面没有声明,则指定的类属于最内层 非类作用域,但如果它随后被引用,则在最里面的封闭非类作用域中提供匹配的声明之前,不会通过名称查找找到它的名称。

      【讨论】:

      • 不,真的是::B: ideone.com/bEgZrq。注意“最里面的封闭 non-class 范围”。
      • @K-ballo 所以当它说声明一个新类时,这仅仅是为了朋友声明的目的,而不是为了其他任何好处吗?
      • @K-ballo 那就是我的困惑所在。我假设 declares 意味着它也将名称带入了范围,并忽略了 在提供匹配的声明之前无法通过名称查找找到它的名称部分。
      猜你喜欢
      • 2011-02-04
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多