为啥 std::array<std::pair<int,int>, 3> 不能使用嵌套初始化列表初始化,但 std::vector<std::pair<int,in

Posted

技术标签:

【中文标题】为啥 std::array<std::pair<int,int>, 3> 不能使用嵌套初始化列表初始化,但 std::vector<std::pair<int,int>> 可以?【英文标题】:Why can't std::array<std::pair<int,int>, 3> be initialized using nested initializer lists, but std::vector<std::pair<int,int>> can?为什么 std::array<std::pair<int,int>, 3> 不能使用嵌套初始化列表初始化,但 std::vector<std::pair<int,int>> 可以? 【发布时间】:2021-03-19 17:17:44 【问题描述】:

请参阅此示例:https://godbolt.org/z/5PqYWP

为什么这个对数组不能像对向量一样初始化?

#include <vector>
#include <array>

int main()

    std::vector<std::pair<int,int>>    v1,2,3,4,5,6; // succeeds 
    std::array <std::pair<int,int>, 3> a1,2,3,4,5,6; // fails to compile

【问题讨论】:

今天询问了very similar question,但使用struct 而不是std::pair。但是这里的答案与这里的答案几乎相同,恕我直言。 (或者可能不是——那个是关于赋值而不是构造函数?) @AdrianMole 但使用struct 而不是std::pair 我希望std::pair 实际上是一个(模板)struct。 ;-) @Scheff 我不能不同意(即使我愿意,但我不同意)。 【参考方案1】:

您需要添加一对外部大括号来初始化std::array&lt;...&gt; 对象本身:

std::array <std::pair<int,int>, 3> a1,2,3,4,5,6;

最外面的对是数组对象,第二对是对象内部的聚合数组。然后是数组中的元素列表。

【讨论】:

那么为什么vectorarray 不同? std::array 是一个聚合,因此您需要 来构造std::array 类,并使用 来构造它的成员数组。 std::vector 有一个使用std::initializer_list 的构造函数,因此构造向量的 会自动调用它。 @MooingDuck 啊,这实际上是两种不同的机制?带有向量的显式构造函数,以及带有数组的普通旧聚合初始化? @MooingDuck 另外:我可以聚合初始化一个 std::vector(它肯定也是一个聚合)吗? @Peter-ReinstateMonica:不。“聚合”基本上是“一个成员都是公共的并且没有显式构造函数的类”,它允许您直接构造std::array 的数组成员。相反,std::vector 具有您自己无法访问的私有成员和自定义构造函数,因此它不是聚合。【参考方案2】:

类模板std::array 的特化表示包含另一个聚合的聚合。

错误的原因是这个声明中的第一个大括号初始化器

std::array <std::pair<int,int>, 3> a1,2,3,4,5,6;
                                     ^^^^^

被认为是内部聚合的初始化器。在这种情况下,以下大括号初始化器被视为冗余初始化器。

所以你可以写任何一个

std::array <std::pair<int, int>, 3> a  1,2,3,4,5,6  ;
                                       ^                   ^
                                       |the inner aggregate|

或喜欢

std::array <std::pair<int, int>, 3> a std::make_pair( 1, 2 ), std::make_pair( 3, 4 ), std::make_pair( 5, 6 ) ;

【讨论】:

值得一提的是std::array没有initializer_list构造函数,vector有。 @iwans std::array 是一个聚合。它没有用户声明的构造函数。:) @VladfromMoscow 太糟糕了,不是吗? @Peter-ReinstateMonica 我不这么认为。这个类(聚合)模拟一个数组,而数组又是一个聚合。

以上是关于为啥 std::array<std::pair<int,int>, 3> 不能使用嵌套初始化列表初始化,但 std::vector<std::pair<int,in的主要内容,如果未能解决你的问题,请参考以下文章

为啥 std::array<std::pair<int,int>, 3> 不能使用嵌套初始化列表初始化,但 std::vector<std::pair<int,in

为啥我可以从 初始化常规数组,而不是 std::array

为啥 std::array::size constexpr 具有简单类型(int,double,...)而不是 std::vector (GCC)?

我不知道为啥我不能在 C++ 中初始化一个数组的数组

在现代 C++ 中将 std::array<std::array<T,N>> 转换为 std::vector<T>

std::vector<std::array<T, N>> 或 std::array<std::vector<T>,N> 类型的数组如何存储在内存中?