何时为 built-in 类型和运算符包含 headers?
When to include headers for built-in types and operators?
什么时候应该为 built-in 类型包含 headers?
<new>
for new
(似乎对于复杂的重载来说确实是需要的);刚好可以用
- (编辑:错误示例(参见答案))
<typeinfo>
for std::type_info
;它可以通过使用 typeid
operator 来获取
- (编辑:错误示例(参见答案))
<initializer_list>
for std::initizlizer_list
;它只是 auto l = {1, 2, 3};
的结果或 for (int i : {1, 2, 3}) {}
中的临时结果
<cstddef>
/<cstdio>
/<cstring>
/<ctime>
对于 std::size_t
;它可以作为运算符 sizeof val
或 sizeof(Type)
的结果给出
<cstddef>
对于 std::nullptr_t
; decltype(nullptr)
<cstddef>
对于 std::ptrdiff_t
; decltype(std::declval<int *>() - std::declval<int *>())
<tuple>
用于结构化绑定的某些功能
- 也许还有其他人
是否存在强制包含相应 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 #pragma
s, 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。
什么时候应该为 built-in 类型包含 headers?
<new>
fornew
(似乎对于复杂的重载来说确实是需要的);刚好可以用- (编辑:错误示例(参见答案))
<typeinfo>
forstd::type_info
;它可以通过使用typeid
operator 来获取
- (编辑:错误示例(参见答案))
<initializer_list>
forstd::initizlizer_list
;它只是auto l = {1, 2, 3};
的结果或for (int i : {1, 2, 3}) {}
中的临时结果
<cstddef>
/<cstdio>
/<cstring>
/<ctime>
对于std::size_t
;它可以作为运算符sizeof val
或sizeof(Type)
的结果给出
<cstddef>
对于std::nullptr_t
;decltype(nullptr)
<cstddef>
对于std::ptrdiff_t
;decltype(std::declval<int *>() - std::declval<int *>())
<tuple>
用于结构化绑定的某些功能- 也许还有其他人
是否存在强制包含相应 headers 的情况?
严格来说,并非所有示例的行为都如您预期的那样。例如
[expr.typeid]
6 If the header
<typeinfo>
is not included prior to a use oftypeid
, 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 ofstd::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 #pragma
s, 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。