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

tzcvj98z  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(121)

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

class A;

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

class A {
    static const int c=5;
};

字符串
在N3797工作草案的3.4.3/1中对此没有任何说明:
类或命名空间成员或枚举数的名称可以在::scope解析运算符(5.1)之后引用,该运算符应用于表示其类、命名空间或枚举的nested-name-specifier
那么这个行为依赖于实现吗?

kx1ctssn

kx1ctssn1#

简介

标准中有几个地方暗示你的代码是格式错误的,但下面的引用本身就说明了这一点:
3.3.2p6声明点[basic.scope.pdecl]
在声明类成员之后,可以在其类的作用域中查找成员名称。
你的代码的问题不在于你试图到达一个不完整类型的主体内部,问题在于你只能在声明了一个类成员名**之后才能引用它。
因为你的前向声明(当然)没有引入任何名为 c 的成员,引用这样的名字是不正确的。

误导性诊断...

gccclang 发布的诊断有点误导,老实说,我觉得一个bug报告是正确的。

foo.cpp:3:8: error: incomplete type 'A' named in nested name specifier

字符串
我们允许在 nested-name-specifier 中命名一个不完整的类型,但正如前面所说的,我们不允许引用一个尚未声明的成员。

  • 格式不正确:*
class X {
  static int a[X::x];        // ill-formed, `X::x` has not yet been declared
  static int const x = 123;
};

  • 法律的:*
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
};

uz75evzq

uz75evzq2#

当我访问一个类的成员变量时,我得到了同样的错误,这个类在头文件中被前向声明,但没有包含在我访问它的main文件中。
myClass.h

class FowardInclude; // has member "int x", but only forward-declared here

class MyClass {
public:
    void foo(int num);
}

字符串
main.cpp

#include "forwardInclude.h" // <-- This is the line I was missing
#include "myClass.h"

MyClass m;
m.foo(ForwardInclude::x);

相关问题