为什么不能使用简单的大括号初始化方式初始化二维std::array?

62

可能重复:
c++ why initializer_list behavior for std::vector and std::array are different

我定义了一个简单的二维数组(3X2):

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

我很惊讶这个初始化不起作用,在gcc4.5中产生错误:too many initializers for 'std::array<std::array<int, 3u>, 2u>'

为什么我不能使用这种语法?

我找到了解决方法,其中一个非常有趣,需要额外的括号,但我只是想知道为什么第一种最简单的方法无效?

解决方法:

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

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

[更新]

好的,感谢KerrekSB和评论区的帮助,我明白了区别。所以似乎在我的例子中括号太少了,就像这个C语言的例子:

struct B {
  int array[3];
};
struct A {
  B array[2];
};

B b = {{1,2,3}};
A a = {{
     {{1,2,3}},
     {{4,5,6}}
}};

std::array 是一个聚合体。 - chris
我也希望这个能够工作。另外一个解决方法是省略内部大括号,尽管在gcc 4.8上会产生警告。 - juanchopanza
1
多维情况与单维情况并无区别,尽管编译器支持可能有所不同。std::array<int, 2> a{1,2};也是不合法的(gcc 4.7.2将错误地接受这样的代码,而clang 3.1则不会)。请参见我上面链接的重复问题。简短的回答是:这是C++11语言标准中已知的缺陷。 - James McNellis
1个回答

80

std::array<T, N> 是一个聚合体,包含一个 C 数组。要初始化它,需要为类本身使用外括号,为 C 数组使用内括号:

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

将这个逻辑应用于二维数组得到如下结果:
std::array<std::array<int, 3>, 2> a2 { { { {1, 2, 3} }, { { 4, 5, 6} } } };
//                                   ^ ^ ^ ^            ^ ^
//                                   | | | |            | |
//                                   | +-|-+------------|-+
//                                   +-|-+-|------------+---- C++ class braces
//                                     |   |
//                                     +---+--- member C array braces

6
这个表达是正确的:std::array<int,3> a1 { 1, 2, 3 }; - PiotrNycz
5
只有在非常粗心并忽略所有警告的情况下,你的编译器才会提示“warning: missing braces around initialiser for ‘std::array<int, 3u>::value_type [3] {aka int [3]}’ [-Wmissing-braces]”。请注意,这里的警告信息是在提醒你缺少花括号。 - Kerrek SB
@PiotrNycz 根据标准的解读,std::array 不要求作为单个元素聚合体实现。我理解 §23.3.2.1 是在说明它可以按照你的第一个示例进行初始化。所以我认为单括号语法是正确的。 - juanchopanza
1
@juanchopanza 在评论中提到,这是C++11中已知的一个bug,也许有一天我们可以使用单括号... - PiotrNycz
这是一个很好的评论。我一直想知道为什么我们需要双括号,但没有太多思考。现在它更有意义了。 - Sebastian
显示剩余8条评论

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