30
4

2 回答 2

27

不幸的是,std::array没有初始化列表构造函数。实际上,它没有任何用户定义的构造函数——这个“特性”是 C++03 的遗留物,在 C++03 中省略所有用户定义的构造函数是启用 C 样式大括号初始化的唯一方法。恕我直言,这是当前标准中的一个缺陷。

那么为什么在这种情况下内置大括号初始化不起作用呢?让我们看看std::array引擎盖下的样子:

template <typename T, int i> struct array {
    T data[i];
    // ...
}

好的,这是否意味着我们必须在初始化程序中使用array括号(一对用于,另一对用于data成员?

std::array<int, 2> a = { {1, 2} };

C(以及因此 C++)有一个关于括号省略的特殊规则,允许省略内括号,除非有歧义。array利用此功能,允许我们编写

std::array<int, 2> a = { 1, 2 };

那么为什么原始帖子中的示例不起作用?因为大括号省略只允许在 C 样式聚合初始化的上下文中,而不是在涉及任何更复杂的情况下,例如用户定义的初始化列表构造函数。

但是,以下应该可以工作,尽管它很丑陋:

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

在我看来,至少在 gcc 4.5 和 gcc 4.6 上没有,这似乎表明存在编译器错误。不过,我对此并不完全确定。

这个问题有点相关:如何使用 initializer_list 初始化成员数组?

于 2011-05-18T10:16:51.957 回答
4

这有效:

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

深入挖掘,似乎 std::pair 有一个构造函数,它接受一个初始化列表,但 std::array 没有:

std::pair<int, int> p ({1,2}) ;  // OK
std::array<int, 2> a ({1,2}) ;   // Invalid

但现在我已经超出了我的深度。

于 2011-05-18T08:07:49.683 回答