【问题标题】:Assigning a braced-init-list to STL containers in C++11在 C++11 中将花括号初始化列表分配给 STL 容器
【发布时间】:2018-03-22 16:27:28
【问题描述】:

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

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

std::vector

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

  • 用初始化列表标识的内容替换内容 列表。 (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。

【问题讨论】:

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


    【解决方案1】:

    参见defect #1527,它将[expr.ass]/9 中的措辞从“由用户定义的赋值运算符定义的赋值” 更改为“对类类型对象的赋值” - 也就是说,运算符不必是用户定义的。我假设你使用的编译器已经解决了这个缺陷。

    【讨论】:

    • 好的,所以隐式定义的复制分配不接受初始化列表,但是将初始化列表分配给类数组的对象会在初始化列表之外创建一个临时数组对象(根据 12.2),哪个本身是使用聚合初始化来初始化的?然后通过隐式定义的复制分配来分配 std::array 类型的临时变量?
    • 我认为arr = {{1, 2, 3, 4}}; 等同于arr = array&lt;int, 4&gt; {{1, 2, 3, 4}}; 是否正确?
    • 是的,我的理解是两者是等价的。
    • 我认为被调用的是移动赋值运算符,而不是复制赋值运算符。
    【解决方案2】:

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

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

    请注意,这不适用于内置数组,它们根本无法赋值。

    【讨论】:

      猜你喜欢
      • 2018-04-20
      • 2014-02-04
      • 2020-05-14
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多