C++:使用 "auto" 在二维数组上嵌套 For 循环
C++: Nested For-loops over 2 dimensional array with "auto"
为了在 C++ 中循环一个名为 "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 的数组。
int &(b[3])
等同于 int & b[3]
,即 对长度为三的 int
的引用数组。这与数组 int a[3][3]
.
中元素的类型不对应
数组 int a[3][3]
中的元素属于 int[3]
类型,即 长度为三 的 int
数组。通过将 b
声明为 int(&b)[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 In a declaration T D where D has the form
D1 [ constant-expressionopt] attribute-specifier-seqopt
and the type of the identifier in the declaration T D1 is
“derived-declarator-type-list T”, then the type of the identifier of D
is an array type; if the type of the identifier of D contains the auto
type-specifier, the program is ill-formed. T is called the array
element type; this type shall not be a reference type, the (possibly
cvqualified) type void, a function type or an abstract class
type....
为了在 C++ 中循环一个名为 "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 的数组。
int &(b[3])
等同于 int & b[3]
,即 对长度为三的 int
的引用数组。这与数组 int a[3][3]
.
数组 int a[3][3]
中的元素属于 int[3]
类型,即 长度为三 的 int
数组。通过将 b
声明为 int(&b)[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 In a declaration T D where D has the form
D1 [ constant-expressionopt] attribute-specifier-seqopt
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the identifier of D is an array type; if the type of the identifier of D contains the auto type-specifier, the program is ill-formed. T is called the array element type; this type shall not be a reference type, the (possibly cvqualified) type void, a function type or an abstract class type....