为什么std::vector和std::array的C++initializer_list行为不同
Why is the C++ initializer_list behavior for std::vector and std::array different?
代码:
std::vector<int> x{1,2,3,4};
std::array<int, 4> y{{1,2,3,4}};
为什么我需要std::array的双大括号?
std::array<T, N>
是一个聚合:它没有任何用户声明的构造函数,甚至没有一个接受std::initializer_list
的构造函数。使用大括号的初始化是使用聚合初始化执行的,这是继承自C.的C++特性
聚合初始化的"旧式"使用=
:
std::array<int, 4> y = { { 1, 2, 3, 4 } };
使用这种老式的聚合初始化,可能会省略额外的大括号,因此这相当于:
std::array<int, 4> y = { 1, 2, 3, 4 };
然而,这些额外的大括号只能在"形式为T x = { a };
的声明"(C++11§8.5.1/11)中删除,也就是说,当使用旧式=
时。此允许省略大括号的规则不适用于直接列表初始化。这里的脚注写道:"括号不能在列表初始化的其他用途中被忽略。"
有一份关于该限制的缺陷报告:CWG缺陷#1270。如果所提出的解决方案被采用,括号省略将被允许用于其他形式的列表初始化,并且以下内容将被很好地形成:
std::array<int, 4> y{ 1, 2, 3, 4 };
(向Ville Voutilainen提供查找缺陷报告的帽子提示。)
因为std::vector
提供了一个接受std::initializer_list<T>
的构造函数,而std::array
没有构造函数,而且{1, 2, 3, 4}
支持的init列表实际上没有被解释为std::initializer_list
,而是std::array
的内部C样式数组的聚合初始化(这就是第二组大括号的来源:一个用于std::array
,一个用于内部C样式成员数组)。
相关文章:
- 使用std::multimap迭代器创建std::list
- 使用"std::unordereded_map"映射到"std::list"对象
- 使用std::list创建循环链表
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 包含 std::list 的结构体的 C++ 初始化
- 在基于范围的 for 循环期间插入 std::list 的后面
- 循环挂起迭代的 std::擦除 on std::list
- 如何增加以前由新运算符分配的 C++ std::list 数组的大小?
- std::list 中的迭代器感知对象
- std::list 可以用于简单的无锁队列吗?
- 使用 std::list 存储顶点并使用 SFML 绘制它们
- C++11 基于范围的 for 循环,用于 std::list
- 向 std::list 添加新元素的复杂性
- 如何使用 std::list 模板的迭代器擦除
- 将元素添加到 std::list 在多线程中,无需 C++ 互斥锁
- 如何将文件的一部分读取到std::list缓冲区?
- 抽象和派生与std::list相结合
- std::list 的两个 insert() 方法签名之间的实现差异
- C++:我可以重用/移动 std::list 元素从中间到结尾吗?