在C ++ 11

时间:2018-03-22 16:27:28

标签: c++11 stl assignment-operator initializer-list

我注意到,除了初始化之外,我还可以将初始化列表分配给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;
}

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

初始化列表

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

的std ::阵列

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

的std ::矢量

矢量&安培; operator =(std :: initializer_list ilist);

  • 将内容替换为初始化列表标识的内容 i列表。 (自C ++ 11起)

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

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

how to assign an array from an initializer list

Error: Assigning to an array from an initializer list

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

2 个答案:

答案 0 :(得分:3)

请参阅defect #1527,其中 [expr.ass] / 9 中的措辞从“更改了由用户定义的赋值运算符”定义的赋值“对类类型对象的赋值” - 也就是说,运算符不必是用户定义的。我假设您使用的编译器已经实现了此缺陷的分辨率。

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

答案 1 :(得分:2)

没有为std::array定义的赋值运算符接受initializer_list

然而,隐式定义的赋值运算符(它本身是std::array)的参数可以从初始化列表中构造。这就是这里发生的事情。

请注意,这对内置数组不起作用,根本无法分配。