为了遍历名为"a C++"的 3x3 数组,我使用了以下代码。
int a[3][3] {};
for(auto &b: a) {
for(auto &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;
}
}
但这行不通。相反,我发现以下内容有效。
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(类型空,函数类型或抽象类 类型....
int &(b[3])
等价于int & b[3]
,即对长度为三的int
的引用数组。这与数组int a[3][3]
中的元素类型不对应。
数组int a[3][3]
中的元素是int[3]
类型,即长度为三的int
数组。通过将b
声明为int(&b)[3]
,可以声明对此类类型的引用。