为什么无法使用嵌套初始化列表对std::array<std::pair<int,int>, 3>进行初始化,但可以对std::vector<std::pair<int,int>>进行初始化?

21

看这个例子:https://godbolt.org/z/5PqYWP

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

#include <vector>
#include <array>

int main()
{
    std::vector<std::pair<int,int>>    v{{1,2},{3,4},{5,6}}; // succeeds 
    std::array <std::pair<int,int>, 3> a{{1,2},{3,4},{5,6}}; // fails to compile
}

2
今天有一个非常相似的问题被问到了,但是使用的是 struct 而不是 std::pair。但是在我看来,那里的答案与这里的任何答案都差不多。也许不一样吧 - 那个问题是关于赋值而不是构造函数的? - Adrian Mole
2
@AdrianMole 但是使用struct代替std::pair,我认为std::pair实际上是一个(模板)struct。;-) - Scheff's Cat
1
@Scheff 我不得不同意(即使我想反驳,但我并不想这样做)。 - Adrian Mole
2个回答

24

您需要添加一对外部花括号来初始化 std::array<...> 对象本身:

您需要在初始化std::array<...>对象本身时添加一对外部大括号:

std::array <std::pair<int,int>, 3> a{{{1,2},{3,4},{5,6}}};

最外层的一对括号是指数组对象,第二对括号是指对象内的聚合数组。然后是数组中元素的列表。


2
那么为什么vectorarray不同呢? - user253751
6
std::array是一个聚合类型,因此您需要使用大括号{}来构造std::array类,并且还需要使用另一组大括号来构造其成员数组。而std::vector有一个接受std::initializer_list的构造函数,因此使用大括号{}来构造向量会自动调用该构造函数。 - Mooing Duck
1
@MooingDuck 啊,所以这实际上是两种不同的机制?一个带有向量的显式构造函数,和一个使用数组的普通聚合初始化? - Peter - Reinstate Monica
@MooingDuck 另外:我可以用聚合初始化语法对 std::vector 进行聚合初始化吗?(因为 std::vector 也是一个聚合类型) - Peter - Reinstate Monica
@Peter-ReinstateMonica:不是的。 "Aggregate" 基本上是指“其所有成员都是公共的且没有显式构造函数的类”,这使您可以直接构造 std::array 的数组成员。相反,std::vector 有私有成员,您无法自己访问,并且具有自定义构造函数,因此它不是一个聚合体。 - Mooing Duck

14
类模板std::array的特化表示封装另一个聚合体。

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

std::array <std::pair<int,int>, 3> a{{1,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 ) };

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接