为什么<initializer_list>使用自动必须包括在内?
Why must <initializer_list> be included for using auto?
SO上已经有一个类似的问题,但我想强调大括号初始化列表的另一个方面。请考虑以下事项:
auto x = {1}; //(1)
这是格式不正确的 (8.5.4/2(,除非包含标头<initializer_list>
。但是为什么?该标准说,模板std::initializer_list
不是预定义的。这是否意味着声明 (1( 引入了一种新的类型?在所有其他可能使用auto
的情况下,例如
auto y = expr;
如果expr
是表达式,则自动推断的类型已存在。另一方面,从逻辑的角度来看,编译器必须为构造{1}
分配一个隐式类型,然后std::initializer_list
是另一个名称。但是在声明 (1( 中,我们不想命名此类型。那么为什么必须包含此标头。nullptr
也有类似的情况。它的类型隐式存在,但要显式命名它,您必须包含<cstddef>
。
这是不一样的。std::nullptr_t
和std::initializer_list
的规则实际上是不同的。
std::nullptr_t
只是内置类型的 typedef。它的定义是
namespace std {
using nullptr_t = decltype(nullptr);
}
无论是否包含标头,该类型都存在。
std::initializer_list
是类模板,而不是预定义类型。除非包含定义它的标头,否则它实际上不存在。特别是,初始值设定项列表{ 1 }
没有类型 std::initializer_list<int>
;它根本没有类型,因为它不是一个表达式。(初始值设定项列表是特殊的语法构造,不能出现在表达式可以出现的所有位置。
std::initializer_list
只是有点特别。首先,对于如何从初始值设定项列表语法初始化std::initializer_list
有特殊规则(分配数组并让对象引用它(。但是,这首先需要定义std::initializer_list
。
第二种特殊情况是auto
型扣除。这里还有一个特殊的规则。但同样,这并不意味着编译器会自动定义类型;这只是意味着它会识别它。
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 为什么 cmake 许可证<>样式不包括?
- 计算平均值,不包括上次得分
- 从多个源构造一个对象,包括一个对象向量
- 在编译中包括 Botan 2
- 将值从另一个数组写入数组,不包括不需要的值 C++
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- 包括C++头文件
- CPP 包括 Azure DevOps 中的目录设置
- 包括STL,而不会乱扔全球范围
- 如何反转我的输入,包括否定
- 包括没有完整路径的我的库
- 如何在 android ndk 上链接 C 和 C++ 代码,以及 C 和 C++ 运行时库(包括 STL)?
- C++包括类名间距和类实例化
- 链接错误,包括我创建的相同头文件 - C++
- 标头,包括在 Swift 项目中使用C++文件时的错误
- 如果语句不包括文本行?
- 如何将字符串与结构(也包括字符串)进行比较?
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?