看到std :: vector <typo>和std :: vector <struct typo =“”>时发出的编译器诊断之间的区别背后的原因是什么?

时间:2019-01-31 12:47:07

标签: c++ compiler-errors

考虑这两个程序及其尝试的编译。

#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’

向量实例化当然都是错误,但是程序注释中引用的不同诊断消息的原理是什么?

1 个答案:

答案 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 -取决于要编译的标准以及所使用的向量的成员。添加了对不完整类型的支持。