c++ - 为什么在 C++14 中对数组的初始化仍然需要双括号?

标签 c++ c++14 initializer-list

使用 C++14 标准,std::array 的初始化可以使用单括号(参见 http://en.cppreference.com/w/cpp/container/array):

但是,这不适用于 std::pairstd::array

为什么这些工作:

std::pair<int, int> p { 1, 2 };
std::array<int, 3> a {1, 2, 3};

但是这有效吗:

std::array<std::pair<int, int>, 3> b {{1, 11}, {2, 22}, {3, 33}};

虽然这又起作用了?

std::array<std::pair<int, int>, 3> b {{{1, 11}, {2, 22}, {3, 33}}};

另外,为了完成,一个好的旧数组的初始化确实可以使用单括号

std::pair<int, int> c[3] {{1, 11}, {2, 22}, {3, 33}};

最佳答案

这似乎是一个类似于著名的 most vexing parse 的解析歧义。 .我怀疑发生了什么:

如果你写

std::array<std::pair<int, int>, 3> b {{1, 11}, {2, 22}, {3, 33}};

编译器有两种解释语法的方式:

  1. 你执行一个全括号初始化(意味着最外面的大括号指的是 std::array 的聚合初始化,而第一个最里面的大括号初始化 std::array 的内部成员表示,它是一个真正的 C 数组)。这将无法编译,因为 std::pair<int, int>随后无法被 1 初始化(所有大括号都用完了)。 clang 将给出一个编译器错误,确切地表明:

    error: no viable conversion from 'int' to 'std::pair<int, int>'
     std::array<std::pair<int, int>, 3> a{{1, 11}, {2, 22}, {3, 33}};
                                              ^
    

    请注意,如果没有要初始化的内部成员聚合,也可以解决此问题,即

    std::pair<int, int> b[3] = {{1, 11}, {2, 22}, {3, 33}};
    

    将编译为聚合初始化。

  2. (你的意思。)你执行一个大括号省略初始化,因此最里面的大括号用于单个对的聚合初始化,而用于内部数组表示的大括号被省略。请注意,即使没有这种歧义,正如 rustyx's answer 中正确指出的那样, 大括号省略规则不适用于 std::pair不是聚合类型,所以程序仍然是不正确的。

编译器会更喜欢选项 1。通过提供额外的大括号,您可以执行全大括号初始化并消除任何语法歧义。

关于c++ - 为什么在 C++14 中对数组的初始化仍然需要双括号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50598248/

相关文章:

c++11 - 为什么是 int* arr = {};合法的?

c++ - 乱序初始化成员 - 这样可以吗?

c++ - Visual Studio 2010 C++ - 未解析的外部符号

c++ - HLSL 着色器显示有线颜色

c++ - 如何根据条件限制用户定义的模板类型

c++ - 为什么 constexpr 不是所有函数的默认值?

c++ - 在单例中使用已删除的复制构造函数

c++ - VS2013 : Can't create vector from one size_t element

c++ - std::enable_if 更改成员 *variable* 声明/类型

c++ - Visual Studio 2015 "non-standard syntax; use ' &' to create pointer for member"