考虑这两个程序及其尝试的编译。
#include <vector>
int main() {
std::vector<struct Typo> a; // Errors centered around `Typo` being an incomplete type
}
例如, 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
}
例如, gcc 6.3给出的错误集中在Typo
未被定义的地方,包括
prog.cpp:4:14:错误:在此范围内未声明
‘Typo’
向量实例化当然都是错误,但是程序注释中引用的不同诊断消息的原理是什么?
答案 0 :(得分:15)
struct Typo
是一个详细的类型说明符。这会影响名称查找的工作方式。
[basic.lookup.elab]
2:如果精心制作的类型说明符没有嵌套名称说明符, 并且除非elaborated-type-specifier出现在带有 格式如下:
class-key attribute-specifier-seq identifier ;
根据[basic.lookup.unqual]查找标识符,但是 忽略任何已声明的非类型名称。如果 enum关键字介绍了elaborated-type-specifier, 查找找不到先前声明的类型名称, 详细类型说明符格式错误。如果 精致的类型说明符是由class-key引入的 查找找不到先前声明的类型名称,或者 elaborated-type-specifier出现在声明中,格式为:
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 -取决于要编译的标准以及所使用的向量的成员。添加了对不完整类型的支持。