c++ - std::array<std::vector> 中的大括号省略

标签 c++ c++17 list-initialization

我正在为 C++ 17 使用 g++ 进行编译。我有以下内容:

std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};

我不明白为什么如果我删除数组的双括号它就不再起作用了。

std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile

我了解 std::array 的工作原理以及通常需要双大括号,但在为 C++17 进行编译时,我希望大括号省略发挥作用。

为什么大括号省略在这里不适用?

最佳答案

std::array<std::vector<int>, 2>是有效的

struct array {
    std::vector<int> elems[2];
};

elems是一个子聚合就好了。问题是根据语言规则,如果初始化程序以 { 开头总是假设您没有去掉大括号;相反,{1, 2}被视为整个子聚合的初始化器 elems , 试图用 1 初始化它的第一个元素第二个元素为 2 (这显然是无效的 - 你不能将整数转换为 vector - 但不影响解释),并且 {3, 4}被认为是 elems 之后的事物的初始化器- 因为没有这样的东西,这是另一个错误。

用不是 braced-init-list 的东西初始化第一个元素足以触发大括号省略:

std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} }; 

请注意,从规范的角度来看,库不保证 std::array<T, N> 的初始化来自除另一个以外的任何东西 std::array<T, N>或“类型可转换为 T 的最多 N 个元素”的列表。这特别排除了 braced-init-list,因为它们没有类型,而且实际上也不允许“双括号”,因为这只是具有一个 braced-init 的单个元素的特殊情况-列表

这是一个我们最好用代码指定它的区域。核心语言规则违背了简单的文字规范,实现细节将会泄露 - 并且已经这样做了。

关于c++ - std::array<std::vector> 中的大括号省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53305831/

相关文章:

C++ 类包装器和放置 new

c++ - 如何通过 MFC 将应用程序设置保存在注册表中?

c++ - 使用扩展元组参数调用成员函数 std::invoke 与 std::apply

c++ - 为什么 braced-init-list 在函数调用和构造函数调用中的行为不同?

c++ - "::function()"在cpp中是什么意思?

C++ - Bool 到 int 转换错误

c++ - const vs非const内联变量

c++ - static_assert 一个类型属于 std::variant 接受的类型

c++ - 为什么具有私有(private)成员的聚合不支持 C++ 大括号初始化?

c++ - MSVC 用 double 支撑初始化似乎违反了标准?