Bat*_*eba 12 c++ compiler-errors
考虑这两个程序及其尝试的编译.
#include <vector>
int main() {
std::vector<struct Typo> a; // Errors centered around `Typo` being an incomplete type
}
Run Code Online (Sandbox Code Playgroud)
例如,gcc 6.3提供以Typo不完整类型为中心的错误消息,包括
/usr/include/c++/6/bits/stl_vector.h:161:9:错误:无效使用不完整类型'
struct main()::Typo'
#include <vector>
int main() {
std::vector<Typo> b; // Errors centred around `Typo` not being defined
}
Run Code Online (Sandbox Code Playgroud)
例如,gcc 6.3给出了以Typo未定义为中心的错误,包括
prog.cpp:4:14:错误:
‘Typo’未在此范围内声明
两个向量实例化当然都是错误的,但是程序注释中引用的不同诊断消息的基本原理是什么?
Sto*_*ica 15
struct Typo是一个精心设计的类型说明符.这会影响名称查找的工作方式.
[basic.lookup.elab]
2:如果elaborated-type-specifier没有嵌套名称说明符,除非elaborated-type-specifier出现在具有以下形式的声明中:
Run Code Online (Sandbox Code Playgroud)class-key attribute-specifier-seq identifier ;根据[basic.lookup.unqual]查找标识符,但忽略已声明的任何非类型名称.如果enum关键字引入了elaborated-type-specifier,并且此查找未找到先前声明的类型名称,则elaborated-type-specifier的格式不正确.如果由类键引入了elaborated-type-specifier,并且此查找未找到先前声明的类型名称,或者如果elaborated-type-specifier出现在具有以下形式的声明中:
Run Code Online (Sandbox Code Playgroud)class-key attribute-specifier-seq identifier ;elaborated-type-specifier是一个声明,它引入了[basic.scope.pdecl]中描述的类名.
因此std::vector<struct Typo> a;,因为struct Typo找不到先前声明的Typo,它作为该类型的前向声明.正因为如此,它的载体实例即可以1抱怨它得到的类型是不完整的,因为它会尝试做的东西吧.
在里面std::vector<Typo> b;,Typo查找什么也没发现.之前没有声明,所以此时应该发出一个诊断,证明该标识符是未声明的.
1 - 取决于您要编译的标准,以及您正在使用的矢量成员.增加了对不完整类型的支持.