C++循环依赖 - 命名空间与结构

Dea*_*ive 13 c++ namespaces

请教育我.为什么编译:

struct compiles
{
    struct A;
    struct B
    {
        B(const A &a) : member(a.member) { }
        int member;
    };
    struct A
    {
        A(const B &b) : member(b.member) { }
        int member;
    };
};
Run Code Online (Sandbox Code Playgroud)

虽然这不是:

namespace doesnt
{
    struct A;
    struct B
    {
        B(const A &a) : member(a.member) { }
        int member;
    };
    struct A
    {
        A(const B &b) : member(b.member) { }
        int member;
    };
}
Run Code Online (Sandbox Code Playgroud)

(在MSVC 9.0中)

Jer*_*ock 14

一次处理class/ struct/ union定义的主体,允许引用稍后定义的类的成员.A namespace从上到下进行处理,前向声明struct A不允许您在没有定义的情况下使用其成员.尝试将B类构造函数的定义移到类外,这样就可以在定义之后放置它A.


CB *_*ley 7

在C++中,类范围很特殊.任何延伸到或超过类定义的声明都会自动扩展到由其成员定义(3.3.6 [basic.scope.class])定义的区域.

这意味着在第一种情况下,第一个声明struct A和完整定义struct A都在主体B及其构造函数中可见.

这不适用于命名空间范围,因此在a.member构造函数中的第二种情况B是错误,因为定义struct A尚不可见.