如何对std::pairs类型的std::array进行支撑初始化?

35
std::array<std::pair<int, int>, 2> ids = { { 0, 1 }, { 1, 2 } };

VS2013错误:

错误 C2440:'initializing':无法将'int'转换为'std::pair'。没有构造函数可以接受源类型,或者构造函数重载解析存在歧义。

我做错了什么?

2个回答

39
添加另一对大括号。
std::array<std::pair<int, int>, 2> ids = { { { 0, 1 }, { 1, 2 } } };

std::array<T, N> 是一个聚合类,其中包含类型为 T[N] 的成员。通常情况下,您可以像初始化普通的 T[N] 数组一样初始化它,但当您处理非聚合元素类型时,您可能需要更加明确。


这似乎解释了一切,直到你看到Joachim使用std::make_pair的答案。那个没有额外括号的是如何工作的? - TonyK
标准保证能够正常工作的唯一事情是 "array<T, N> a = { initializer-list };",其中 initializer-list 是一个由最多 N 个元素组成的逗号分隔列表,其类型可转换为 T。额外的一对大括号可能在所有当前实现上都可以工作,但不能保证。 - T.C.
1
这里的建议如果数组包含三对时不起作用:std::array<std::pair<int, int>, 3> ids = { { { 0, 1 }, { 1, 2 }, { 2, 3 } } }; 无法编译。然而,去掉 = 就可以了:std::array<std::pair<int, int>, 3> ids { { { 0, 1 }, { 1, 2 }, { 2, 3 } } }; 可以编译而没有错误。我花了很长时间才弄清楚这一点。也许应该编辑答案,以便未来的访问者受到警告?此外,我自己还有一个额外的问题:为什么会这样? - Tim
@Tim,你所说的代码确实可以编译通过。我在 https://gcc.godbolt.org/ 上使用当前和旧版本的GCC、clang、icc和MSVC进行了双重检查。 - user743382
@hvd 哎呀,这很奇怪。抱歉打扰你了。我在 Xcode 中直接比较了两个选项,确实发现了上述问题。但现在我无法再现它了。看起来重启 Xcode 可以让编译错误消失?虽然这种情况很奇怪。 - Tim
显示剩余2条评论

29

std::array是一个聚合类型。它只有一个数据成员 - 指定类型的std::array特化的数组。根据C++标准(8.5.1聚合)。

2 当使用初始化列表在8.5.4中指定的方式初始化聚合时,初始化列表的元素将按递增下标或成员顺序作为聚合的成员的初始值

因此这个记录

std::array<std::pair<int, int>, 2> ids = { { 0, 1 }, { 1, 2 } };

在std::array中,初始化器的数量多于数据成员。

std::array的数据成员是一个聚合体。必须为它提供一个初始化列表。

因此,代码将如下所示:

std::array<std::pair<int, int>, 2> ids = { { { 0, 1 }, { 1, 2 } } };

为了更清晰,你可以这样想象初始化:

std::array<std::pair<int, int>, 2> ids = { /* an initializer for data member of the array */ };
作为数据成员是聚合的,那么您必须编写:

由于数据成员是一个集合,因此您必须编写

std::array<std::pair<int, int>, 2> ids = { { /* initializers for the aggregate data member*/ } };

最后

std::array<std::pair<int, int>, 2> ids = { { { 0, 1 }, { 1, 2 } } };

2
如果您按照标准进行操作,那么不能保证std::array只有一个数据成员。 - T.C.
@T.C. 没有这些信息,您无法正确初始化数组。至少在阐述方面,标准在数组定义中包括以下数据成员 T elems[N]; - Vlad from Moscow
标准确保如果initializer-list中的每个元素都可以转换为T类型且不超过N个元素,则array <T,N> a = {initializer-list};将起作用。不能保证内置数组(如果使用一个 - 我不知道是否可能在不使用它的情况下满足所有要求)是唯一的数据成员。 - T.C.
@T.C. 我也不知道可以用什么替代数组。如果明确写出内部表示是一个数组会更好。 - Vlad from Moscow
对于路过的读者,这个东西现在已经在9.4.2中了。 - Enlico

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