何时为 built-in 类型和运算符包含 headers?

When to include headers for built-in types and operators?

什么时候应该为 built-in 类型包含 headers?

是否存在强制包含相应 headers 的情况?

严格来说,并非所有示例的行为都如您预期的那样。例如

[expr.typeid]

6 If the header <typeinfo> is not included prior to a use of typeid, the program is ill-formed.

[dcl.init.list]

2 ... The template std​::​initializer_­list is not predefined; if the header <initializer_­list> is not included prior to a use of std​::​initializer_­list — even an implicit use in which the type is not named — the program is ill-formed.

现在有两个例子。当然,你可以不包括 一些 headers,例如

using size_t    = decltype(sizeof(0));
using nullptr_t = decltype(nullptr);

但总的来说,完全确定我们得到 well-defined 结果的方法是为标准类型包含适当的 header。

Are there cases when inclusion of corresponding headers is mandatory?

我不是语言律师,C++11 对我来说太难掌握了(见n3337), but on implementations like GCC or Clang a standard header can and often does contain compiler specific tricks like #pragmas, function attributes, or builtins。 今天,在 2019 年底,GCC 至少在 <cstdarg> 中使用了此类技巧,实际上在许多其他情况下(例如,在最近的 Debian 上尝试 grep -rn __attribute__ /usr/lib/gcc/x86_64-linux-gnu/8/)。

我的理解是标准 header 甚至可能不作为文件存在于您的系统上。它在编译器内部可能很神奇,专门处理 #include <map> 以更改编译器的状态。但是,我知道 2019 年没有编译器这样做。据传言,VisualAge 在上个世纪就这样做了。

所以我认为在使用它们时需要包含标准 headers。