嵌套名称说明符中的不完整类型

35 c++ language-lawyer

我尝试在嵌套名称说明符中使用不完整类型,如下所示:

class A;

int b= A::c; // error: incomplete type ‘A’ used in nested name specifier

class A {
    static const int c=5;
};
Run Code Online (Sandbox Code Playgroud)

在N3797工作草案的3.4.3/1中没有提到它:

在应用于表示其类,名称空间或枚举的嵌套名称说明符的:: scope resolution运算符(5.1)之后,可以引用类或名称空间成员或枚举器的名称.

那个行为实现依赖于什么?

Fil*_*efp 40

介绍

标准中有几个地方隐含地暗示您的代码格式不正确,但以下引文不言自明:

3.3.2p6 宣言点 [basic.scope.pdecl]

在声明类成员之后,可以在其类的范围内查找成员名称.

您的代码的问题不在于您尝试到达不完整类型的主体内部,问题是您只能在声明后引用类成员名称.

由于您的前向声明(当然)没有引入任何名为c的成员,因此引用此类名称的形式不明确.


误导性的诊断......

gcc和clang在提供代码时发出的诊断有点误导,老实说我觉得错误报告是有序的.

foo.cpp:3:8: error: incomplete type 'A' named in nested name specifier
Run Code Online (Sandbox Code Playgroud)


我们被允许在嵌套名称说明符中命名一个不完整的类型,但是如上所述; 我们不允许引用尚未申报的成员.

病态的:

class X {
  static int a[X::x];        // ill-formed, `X::x` has not yet been declared
  static int const x = 123;
};
Run Code Online (Sandbox Code Playgroud)

法律:

class X {
  int const x = 123;
  int a[X::x]; // legal, `X` is incomplete (since we are still defining it)
               //        but we can still refer to a _declared_ member of it
};
Run Code Online (Sandbox Code Playgroud)