代码之家  ›  专栏  ›  技术社区  ›  Bathsheba

当编译器看到std::vector<typo>和std::vector<struct typo>时,它发出的诊断结果之间的差异背后的基本原理是什么?

  •  12
  • Bathsheba  · 技术社区  · 6 年前

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

    #include <vector>
    
    int main() {
        std::vector<struct Typo> a; // Errors centered around `Typo` being an incomplete type
    }
    

    例如,GCC 6.3给出了以 Typo 不完整的类型,包括

    /Ur/Eng/C++/6/BIT/STLyValth.H:161:9:错误:不完全类型的无效使用 struct main()::Typo 艾斯

    #include <vector>
    
    int main() {
        std::vector<Typo> b; // Errors centred around `Typo` not being defined
    }
    

    例如,GCC 6.3给出了以 打字错误 未定义,包括

    程序cpp:4:14:错误: ‘Typo’ 未在此范围内声明

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

    1 回复  |  直到 6 年前
        1
  •  15
  •   StoryTeller - Unslander Monica    6 年前

    struct Typo 是一个详细的类型说明符。这会影响名称查找的工作方式。

    [基本.查找.elab]

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

    class-key attribute-specifier-seq identifier ;
    

    根据[basic.lookup.unequal]查找标识符,但 忽略已声明的任何非类型名。如果 详细的类型说明符由枚举关键字引入,并且 查找未找到以前声明的类型名, 详细的类型说明符格式错误。如果 类键引入了详细的类型说明符,并且 查找找不到以前声明的类型名,或者如果 详细的类型说明符出现在声明中,格式为:

    类键属性说明符seq identifier;
    

    详细说明的类型说明符是一个声明,它介绍了 类名称,如[basic.scope.pdecl]中所述。

    所以在 std::vector<struct Typo> a; ,因为 结构类型 找不到以前声明的 Typo ,它用作类型的转发声明。因此,它的向量实例化 可以 抱怨它得到的类型是不完整的,因为它会试图用它做一些事情。

    而在 std::vector<Typo> b; 向上看 打字错误 一无所获。没有以前的声明,因此此时应该发出诊断,以使该标识符未声明。


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