为了在一个名为 "a "的3x3数组上循环,我使用了以下代码。
int a[3][3] {};
for(auto &b: a) {
for(auto &c: b) {
std::cout << c << std::endl;
}
}
如果我必须替换 "auto",我会直观地尝试以下代码
int a[3][3] {};
for(int &(b[3]): a) {
for(int &c: b) {
std::cout << c << std::endl;
}
}
但这并不奏效。而我却想明白了,下面的方法可行。
int a[3][3] {};
for(int (&b)[3]: a) {
for(int &c: b) {
std::cout << c << std::endl;
}
}
那么问题是:为什么后一个例子能用?
我以为我需要一个长度为3的数组的引用,但是我需要一个长度为3的数组,其中包含引用。
如果你有一个像这样的数组
T a[N1][N2][N3];
哪儿 T
是一些类型说明者,并且 N1
, N2
和 N3
数组的大小,那么对这个数组的引用就会看起来像
T ( &ra )[N1][N2][N3] = a;
如果你需要声明一个对数组元素的引用,(该元素)的类型是 T[N2][N3]
那么你可以写例如
T ( &e )[N2][N3] = a[0];
回到你的例子,你声明了一个数组
int a[3][3] {};
该数组中的元素类型为 int[3]
. 因此,要声明对数组元素的引用,你必须写下
for ( int ( %row )[3] : a )
至于这份声明
int &(b[3])
(这里的括号是多余的),然后它声明一个由三个元素组成的数组,类型为 int &
. 然而根据C++标准,你不能声明一个引用数组。
在C++标准中(8.3.4数组)
1 在声明T D中,D的形式为
D1 [ constant-expressionopt] attribute-specifier-seqopt
且声明T D1中的标识符类型为 "派生-声明者类型-列表T",则D的标识符类型为数组类型;如果D的标识符类型中含有自动类型指定符,则程序不健全。T称为数组元素类型;该类型不得是引用类型、(可能是cvqualified)类型void、函数类型或抽象类类型。....
int &(b[3])
相当于 int & b[3]
即 的引用数组。int
其长度为三。这与数组中元素的类型不一致。int a[3][3]
.
阵列中的元素 int a[3][3]
属于 int[3]
即 一系列 int
其长为三. 通过宣布而不是 b
作为 int(&b)[3]
你声明了一个对这样一个类型的引用。