子数组分配:使用聚合对象错误的预期"{...}"进行初始化
Subarray assignment: initialization with "{...}" expected for aggregate object error
对第 1 行的错误有什么好的解释?
/* Line 0 */ int foo[10][10];
/* Line 1 */ int foo_alias_compile_error[] = foo[0];
/* Line 2 */ int foo_alias_also_errors[10] = foo[0];
/* Line 3 */ int * foo_alias_works = foo[0];
第 2 行上的错误并没有真正困扰我,因为我不需要能够重复自己并重新声明数组的大小。 但是,第 1 行上的错误(聚合对象预期使用"{...}"初始化)让我感到困惑。 我知道int foo_alias_compile_error[]
可能是"聚合对象"。 我只是不明白为什么语言设置为不起作用。 我理解为什么第 3 行有效,但它感觉有点不具有代表性——它是一个数组,所以我宁愿把它作为一个数组自我记录。
人们可能希望将第 1 行视为为foo
的第 0 个条目创建引用。 但是,这不是C++的工作方式。 相反,赋值运算符(=
)正在调用复制操作。 因此,C++将第 1 行解释为将foo[0]
元素复制到新数组中的指令,该数组的名称不恰当地命名为foo_alias_compile_error
。
这不是这个意思 - 人们想要一个参考,而不是一个副本。 因此,C++碰巧由于不相关的原因引起了错误并从自己那里节省了一个错误,这很好。
@FrançoisAndrieux提出了一个可行的解决方案。 这是一个更完整的示例,表明可以使用int (&foo_reference)[10] = foo[0];
进行引用(而不是副本)。
int foo[10][10];
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 10; ++j) {
foo[i][j] = i + j * 10;
}
}
int (&foo_reference)[10] = foo[0];
for (int j = 0; j < 10; ++j) {
foo_reference[j] = 100 + j;
}
for (int i = 0; i < 10; ++i) {
printf("foo [0][%i] is %in", i, foo[0][i]);
printf("foo_refer[%i] is %in", i, foo_reference[i]);
}
输出代码段
foo [0][0] is 100
foo_alias[0] is 100
foo [0][1] is 101
foo_alias[1] is 101
foo [0][2] is 102
foo_alias[2] is 102
foo [0][3] is 103
foo_alias[3] is 103
旁注
值得一提的是,将数组作为参数的函数会隐式地将其数组参数转换为指针(如第 3 行所示)。 所以,这就是为什么人们可能错误地认为像1号线这样的东西应该工作的原因之一。
换句话说,以下代码
void barz(int arg[]) {
arg[2] = 99999;
}
int another_array[] = {0, 1, 2, 3, 4};
barz(another_array);
printf("another_array[2] is %in", another_array[2]);
"正确"打印99999
,而不是2
。
数组定义(即 C 样式数组)中的初始值设定项必须是大括号列表。
此规则涵盖第 1 行和第 2 行,其中您提供的内容不是支撑列表,因此代码不正确。
更多信息:当您提供大括号列表时,列表的每个元素都将作为数组元素的初始值设定项。作为推论,不可能提供单个初始值设定项,这会导致它设置多个数组元素。
此规则几乎以递归方式应用;如果您有一个数组数组,则初始值设定项应该是支撑列表的支撑列表。但是,有一条规则是在某些情况下可以省略嵌套大括号(并且代码的行为就像提供了完整的大括号一样)。例如,int x[2][2] = { 1, 2, 3, 4 };
是允许的,其行为类似于int x[2][2] = { {1, 2}, {3, 4} };
。
当您未指定数组大小时(在第 1 行中)。 编译器为您指定它。 为此,您必须这样做:
/* Line 0 */ int foo[10][10];
/* Line 1 */ int foo_alias_compile_error[] = {foo[0]};
但它仍然有一个问题。 编译该代码时:
$ g++ error.cpp
$ error.cpp:4:28: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
$ 4 | int fooError[] = {foo[0]};
$ | ~~~~~^
$ | |
$ | int*
因为foo[0]
是一个指针,指向矩阵的第一行(在第 1 行中)。 您可以这样做:
/* Line 0 */ int foo[10][10];
/* Line 1 */ int foo_alias_compile_error[] = {foo[0][0]};
- 使用默认构造函数引用成员变量初始化错误
- 交换机案例语句中的初始化错误
- 英特尔 MKL 稀疏 QR 求解 C++ 返回未初始化错误
- 在模板类中使用"this"会导致参数初始化错误
- 映射的映射集的映射初始化错误
- C++图形初始化错误(语法或丢失文件缺陷?
- QSQLDATABASE:SIGSEV初始化错误
- 映射的 std::for_each() 给出无效的初始化错误
- 初始化错误过多
- C++初始化错误 std::set
- 简单的类构造函数初始化错误
- 组合框初始化错误:无法读取未定义的属性'constructor'
- OpenCV卡尔曼滤波器初始化错误
- C++11动态数组部分列表初始化(错误或误解)
- C++ 静态变量在发布模式下初始化错误
- Visual Studio 2010 SP1 中的 64 位整数初始化错误
- C++libPNG-简单初始化错误
- 结构数组-初始化错误
- 初始化错误
- 我不断收到函数初始化错误.(运行时检查失败 #3)