在 C++11 中为 STL 容器分配大括号初始化列表



我注意到,除了初始化之外,我还能够将初始值设定项列表分配给 STL 容器,例如 std::array 和 std::vector。例如:

#include <iostream>
#include <array>
#include <vector>
using namespace std;
int main()
{
array<int, 4> arr;
vector<int> vec(4);
arr = {{1, 2, 3, 4}};
vec = {4, 3, 2, 1};
cout << "arr: ";
for (auto elem : arr)
cout << elem << " ";
cout << "nvec: ";
for (auto elem : vec)
cout << elem << " ";
cout << endl;
}

我正在 Clang 3.8.0 上编译此代码,仅使用 -std=C++11 标志。我试图辨别这种行为是由 C++11 标准定义的,还是只是编译器定义的。我一直在尝试通过标准的相关部分(以及 cppreference.com 标准中的语言变得过于复杂时),到目前为止,我已经提出了这个:

初始值设定项列表

5.17.9 - 大括号初始化列表可能出现在由用户定义的赋值运算符定义的赋值的右侧

标准::数组

23.3.2.2:类数组依赖于隐式声明的特殊成员函数...符合容器要求

标准::矢量

vector& operator=( std::initializer_list ilist );

  • 将内容替换为初始值设定项列表标识的内容 伊利斯特。(自C++11起)

从 std::vector 的重载赋值运算符的语法来看,似乎很明显支持初始值设定项列表的赋值。所以我想知道将初始值设定项列表传递给为 STL 容器隐式定义的重载赋值运算符(在我的示例中为 std::array)是否是定义的行为?作为奖励,std::array 是唯一具有隐式定义的重载赋值运算符的 STL 容器吗?

我查看了有关SO的相关问题的答案,例如:

如何从初始值设定项列表中分配数组

错误:从初始值设定项列表分配给数组

但是,给出的答案与我从编译器获得的行为或我从标准中解释的行为不一致。另外,我正在寻找一个更普遍问题的答案,而不仅仅是将列表初始值设定项分配给 std::array。

请参阅缺陷 #1527,它将[expr.ass]/9中的措辞从"由用户定义的赋值运算符定义的赋值">更改为"对类类型对象的赋值">- 也就是说,运算符不必是用户定义的。我假设您使用的编译器已经实现了此缺陷的解决方案。

std::array具有隐式定义的复制赋值operator=(const std::array&)- 这就是被调用的那个,参数是通过聚合初始化临时构造的std::array

没有为接受initializer_liststd::array定义赋值运算符。

但是,隐式定义的赋值运算符(本身就是一个std::array)的参数可以从初始值设定项列表构造。这正是这里发生的事情。

请注意,这不适用于内置数组,根本无法分配这些数组。

最新更新