nested class 的成员函数为什么不需要完整类型?

Why doesn't the member func of nested class need a complete type?

示例:

 class A
{
  class B
  {
    A c;//error!A is an incomplete type
    void test() { A b;/*OK,but why?*/ }
  };
};

代码片段对我来说似乎很奇怪,A的两种用法有什么区别?

[class.mem]/6 指定:

A class is considered a completely-defined object type (6.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, noexcept-specifiers, and default member initializers (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

对象的定义(如A b;A c;)要求对象具有完整的类型。正如上面的段落所述,class 类型在它自己的定义中是不完整的,除了某些地方:即在成员函数体内和其他一些地方。

此规则使得可以在定义为内联的成员函数内编写重要代码,同时还禁止 class 包含自身(直接或间接)。

如编译错误所见:

prog.cpp:8:7: error: field ‘c’ has incomplete type ‘A’
     A c;//error!A is an incomplete type
       ^
prog.cpp:4:8: note: forward declaration of ‘class A’
  class A
        ^

Class A 是一个 forward-declaration 其中:

Declares a class type which will be defined later in this scope. Until the definition appears, this class name has incomplete type. This allows classes that refer to each other:

因为 class A 没有 "fully" 定义,直到 class B 被定义。

因此,class A是一个forward-declaration并且是一个不完整的类型。

然而,对于

void test() { A b;/*OK,but why?*/ }

If forward declaration appears in local scope, it hides previously declared class, variable, function, and all other declarations of the same name that may appear in enclosing scopes:

因此,在本地范围内声明 A 是可以的。