为什么这个C++代码不会出现编译错误?

Nik*_*ema 4 c++ struct pointers structure

#include<iostream>
using namespace std;

struct a{
    int e;
    struct abc *d;
};

struct abc{
    int c;
};

int main()
{
 return 0;  
}
Run Code Online (Sandbox Code Playgroud)

我已经定义了我已经声明了结构指针的struct abc后定义.这应该抛出编译错误,因为它在声明之前使用.但是,它没有,为什么?而当我刚刚取代它,而不是,这是给编译错误预期.struct aabcabcstruct abc dstruct abc *d

Vla*_*cow 6

这个宣言

struct abc *d;
Run Code Online (Sandbox Code Playgroud)

一方面声明struct abc,另一方面声明d类型的指针struct abc *.

在此声明中,不需要具有struct abc的确切定义,因为不使用该结构的数据成员.

该说明符struct abc称为详细类型说明符.

它在给定范围内引入了一个新类型,或者引用了一个已声明的类型.


Lig*_*ica 5

你是对的,通常,你需要这种类型的前向声明:

// Forward declaration
struct bar;

struct foo
{
    bar* d;   // only a pointer-to-bar; forward declaration sufficient
};

struct bar
{
    int c;
};
Run Code Online (Sandbox Code Playgroud)

但是,您(由于某种原因)struct在类型名称之前使用过时的写作习惯.(这在C中是必需的,但从未在C++中使用过.)

struct foo
{
    struct bar* d;
};

struct bar
{
    int c;
};
Run Code Online (Sandbox Code Playgroud)

因为你struct bar在那里写作而不仅仅是bar,它本身就算作各种各样的前瞻性声明.编译器现在知道这bar是一种类型,这就是它需要知道的全部内容.

它有点模糊和微妙,但这就是为什么你不再需要先前的前向声明.

[C++11: 3.1/4]: [注意: 类名也可以由elaborated-type-specifier(7.1.6.3)隐式声明. - 尾注]

[C++11: 3.3.2/6]: 详细说明的类型说明符中首先声明的类的声明点如下:

  • 声明表格

       class-key attribute-specifier-seq opt identifier ;

    识别符被声明为一个类名称在包含声明的范围,否则

  • 对于表单的详细类型说明符

       类密钥标识符

    如果在命名空间作用域中定义的函数的decl-specifier-seqparameter-declaration-clause中使用了elaborated-type-specifier,则在包含声明的命名空间中将标识符声明为类名.否则,不同之处为朋友声明,标识符是在包含声明的最小命名空间或块范围中声明.[注意:这些规则也适用于模板.-end note] [注意:其他形式的elaborated-type-specifier不声明新名称,因此必须引用现有的类型名称.见3.4.4和7.1.6.3. - 尾注]

[C++11: 3.4.4/2]: [..] 如果由类键引入了elaborated-type-specifier,并且此查找未找到先前声明的类型名称,或者如果elaborated-type-specifier出现在具有以下形式的声明中:

   class-key attribute-specifier-seq opt identifier ;

阐述了式说明符是引入了一个声明类名如3.3.2中所述.