初始化嵌套std::array时报错“初始化器过多”的原因是什么
报错原因分析
std::array 是C++标准库定义的聚合类型,它的底层仅包含一个公开的固定大小原生数组成员,没有自定义构造函数,初始化必须严格遵循聚合初始化规则,这是和std::vector行为差异的核心原因。
各初始化场景的合法性解释
- 1维
std::array<int, 3>初始化(FooOK1D)合法:触发了聚合初始化的大括号省略规则,编译器允许省略包裹std::array内部原生数组的那层大括号,直接把1,2,3依次填充到内部数组的三个元素中。 - 2维
std::array初始化(FooOK)合法:同样触发了多层大括号省略,编译器会把1,2,3依次填充到内部第一个std::array<int, 3>的元素中,剩下未显式初始化的元素会被零初始化,符合语法规则。 std::vector初始化(Bar)合法:std::vector不是聚合类型,它提供了接收std::initializer_list参数的构造函数,你传入的三个{1,2,3}每个都是一个std::initializer_list<int>,正好匹配vector<vector<int>>的构造逻辑,因此可以正常编译。Foo初始化报错的核心原因:2维std::array的内部是一个元素类型为std::array<int,3>的原生数组,外层std::array本身只有这一个数组成员。你直接传入三个独立的初始化列表{1,2,3}、{4,5,6}、{7,8,9},相当于试图给外层std::array的三个成员赋值,但外层std::array只有1个内部数组成员,初始化器数量超过了成员数量,因此编译器报「too many initializers」错误。
正确的2维std::array初始化写法
你只需要多补一层大括号,用来包裹std::array的内部原生数组即可:
#include <array> std::array<std::array<int, 3>, 3> Foo { { // 该层大括号对应std::array内部的原生数组 {1,2,3}, {4,5,6}, {7,8,9} } };
你也可以完全省略所有内层大括号,直接平铺所有值,也能符合大括号省略规则正常编译:
std::array<std::array<int, 3>, 3> Foo {1,2,3,4,5,6,7,8,9};
内容的提问来源于stack exchange,提问作者Jabberwocky
相关产品推荐
相关产品推荐

