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 是某种类型说明符,N1N2N3 是数组的大小,那么对该数组的引用将类似于

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....