【问题标题】:Why can't simple initialize (with braces) 2D std::array? [duplicate]为什么不能简单地初始化(带大括号)2D std::array? [复制]
【发布时间】:2012-10-02 09:47:10
【问题描述】:

可能重复:
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&lt;std::array&lt;int, 3u&gt;, 2u&gt;'

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

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

解决方法:

  // 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 和 cmets,我明白了。因此,我的示例中的大括号似乎太少了,就像在这个 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 是一个聚合。
  • 我也希望这能奏效。顺便说一句,另一种解决方法是省略内部大括号,尽管它会在 gcc 4.8 上产生警告。
  • 多维情况与单维情况没有什么不同,尽管编译器支持可能会有所不同。 std::array&lt;int, 2&gt; a{1,2}; 也是格式错误的(gcc 4.7.2 将错误地接受此类代码;clang 3.1 不会)。请参阅我上面链接的副本。简短的回答是:这是 C++11 语言标准中的一个已知缺陷。

标签: c++ stl c++11 initialization


【解决方案1】:

std::array&lt;T, N&gt; 是一个聚合,包含一个 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

【讨论】:

  • 但这工作正常:std::array&lt;int,3&gt; a1 { 1, 2, 3 }; ?
  • @PiotrNycz:仅当您非常草率并忽略所有警告时。我的编译器说,warning: missing braces around initialiser for ‘std::array&lt;int, 3u&gt;::value_type [3] {aka int [3]}’ [-Wmissing-braces].
  • 我现在明白了,谢谢。我用 C 添加到我的问题示例中。
  • @PiotrNycz 我对标准的解读是,std::array 不需要作为单个元素聚合来实现。我将 §23.3.2.1 解释为说明它可以根据您的第一个示例进行初始化。所以我认为单括号语法很好。
  • @juanchopanza James McNellis 在 cmets 中写道,这是 C++11 中的已知错误,也许有一天我们可以使用单括号...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 2013-06-03
  • 2012-07-29
  • 2015-02-24
  • 1970-01-01
  • 2015-08-11
相关资源
最近更新 更多