C++ 朋友声明不转发声明

C++ 朋友声明不转发声明,c++,c++11,C++,C++11,我的理解是,如果使用了class说明符,那么friend声明也可以作为类的转发声明,如本例所示: class A { friend class B; B* b; }; class B {}; int main() {} class X2 { friend Ct; // OK: class C is a friend friend D; // error: no type-name D in scope friend class D; // OK: e

我的理解是,如果使用了
class
说明符,那么
friend
声明也可以作为类的转发声明,如本例所示:

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

class B {};

int main() {}
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
}
但是,g++(4.6.3和4.7.0)给了我以下错误(g++-4.7应该支持),这在没有转发声明的情况下是应该的:

main.cpp:6:2:错误:“B”未命名类型

为了证实我的期望,
朋友B级应该作为一个转发声明,但两者都不是决定性的(或者至少我不能从中得出太多结论),因此我尝试参考c++11标准,发现了以下示例:

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

class B {};

int main() {}
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
}
根据我对第三个声明的阅读,我的
朋友类B
应该是一个声明新类的详细类型说明符


我刚刚开始理解官方的标准措辞,所以我肯定遗漏了什么。我误解了什么?

你的
朋友B班声明确实用作转发声明,但在提供匹配声明之前,不会通过名称查找找到此类声明

[class.friend]/11:

如果友元声明出现在本地类(9.8)中,并且指定的名称是非限定名称,则会查找先前的声明,而不考虑位于最内层封闭非类范围之外的范围。对于友元函数声明,如果没有先前的声明,则程序格式错误。对于友元类声明,如果没有先前的声明,则指定的类属于最内层的封闭类 非类作用域,但如果随后引用了它,则在最内层的封闭非类作用域中提供匹配声明之前,名称查找不会找到它的名称


看看11.3第11段:

对于友元类声明,如果没有先前的声明,则指定的类属于最内层的封闭非类范围,但如果随后引用了该类,则在最内层的封闭非类范围中提供匹配声明之前,不会通过名称查找找到其名称

例如:


不,它确实是
::B
:。注意“最里面的封闭非类范围”。@K-ballo所以当它说声明一个新类时,这仅仅是为了朋友声明的目的,而不是为了其他任何事情?@K-ballo那就是我的困惑所在。我假设声明意味着它也将名称引入范围,忽略了名称查找无法找到其名称的问题,直到提供了匹配的声明。