C++ 看到std::vector<;时发出的编译器诊断之间的差异背后的基本原理是什么;打字错误>;和std::vector<;结构类型>;

C++ 看到std::vector<;时发出的编译器诊断之间的差异背后的基本原理是什么;打字错误>;和std::vector<;结构类型>;,c++,compiler-errors,C++,Compiler Errors,考虑这两个程序及其尝试编译 #include <vector> int main() { std::vector<struct Typo> a; // Errors centered around `Typo` being an incomplete type } 例如,gcc 6.3给出了以未定义的Typo为中心的错误,包括 prog.cpp:4:14:错误:'Typo'未在此范围内声明 当然,这两个向量实例化都是错误的,但程序注释中引用的不同诊断消息的基本

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

#include <vector>

int main() {
    std::vector<struct Typo> a; // Errors centered around `Typo` being an incomplete type
}
例如,gcc 6.3给出了以未定义的
Typo
为中心的错误,包括

prog.cpp:4:14:错误:
'Typo'
未在此范围内声明


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

结构类型输入法是一个详细的类型说明符。这会影响名称查找的工作方式

[basic.lookup.elab]

:如果详细说明的类型说明符没有嵌套的名称说明符, 除非详细的类型说明符出现在带有 以下表格:

class-key attribute-specifier-seq identifier ;
根据[basic.lookup.unqual]查找标识符,但 忽略已声明的任何非类型名称。如果 enum关键字和 查找找不到以前声明的类型名 详细的类型说明符格式不正确。如果 类键和 查找未找到以前声明的类型名,或者 详细说明的类型说明符以以下形式出现在声明中:

class-key attribute-specifier-seq identifier ;
详细的类型说明符是介绍 类名称,如[basic.scope.pdecl]中所述

所以在
std::vector a中,因为
struct Typo
找不到以前声明的
Typo
,所以它充当类型的前向声明。因此,它的向量实例化可能会抱怨它得到的类型是不完整的,因为它会尝试用它来做一些事情

而在
std::vector b中,查找
打字错误
找不到任何内容。它之前没有声明,因此此时应发出诊断,说明此标识符未声明


1-取决于编译的标准以及使用的向量的成员。已添加对不完整类型的支持。

因为这是两件不同的事情?a) “你说有一个打字错误,好吧,我明白了,但它是不完整的”。b) “这附近没有打字错误,伙计。”@SombreroChicken:我是不是一个
std::numeric\u limits::max()
?@user463035818没关系,编译器怎么知道这是一个打字错误?@Bathsheba相当于
std::numeric\u limits::infinity()
。编辑成两个程序,因为这似乎是你们真正想问的问题,为了指定gcc 6.3。精心设计的类型说明符-这很时髦。@Bathsheba-我不会抱怨:)@Pi-请原谅我引用我自己的话“因此,向量实例化可能会抱怨它得到的类型不完整”。@Pi-不,我没有这么说。声明是众所周知的。但是向量试图以不允许的方式使用不完整的类型(例如,创建它的对象)。@jrok DOHHH!!!!!!!!!!!!!!!!!!!:)没有更多的补充。打字错误选得很好。谢谢你指出:D
class-key attribute-specifier-seq identifier ;