【问题标题】:C++: Nested For-loops over 2 dimensional array with "auto"C++:使用“auto”在二维数组上嵌套 For 循环
【发布时间】:2020-05-19 11:44:10
【问题描述】:

为了在 C++ 中循环一个名为“a”的 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 的数组。

【问题讨论】:

  • int (&amp;b)[3] 这是对int[3] 的引用。这是一个棘手的语法。所以你确实有一个长度为 3 的数组的引用。
  • 很遗憾,您的“阅读”是错误的,int &amp;(b)[3] 被解析为引用数组,而int (&amp;b)[3] 是对大小为 3 的数组的引用。(请参阅stackoverflow.com/questions/5724171/…
  • 因为for(int i=0; i&lt;3; i++) for(int j=0; j&lt;3; j++) { std::cout &lt;&lt; a[i][j] &lt;&lt; std:endl; 太容易阅读和简单了。因此,让我们尝试将快速、可读的代码转换成遗忘,C++1x 提供了所有工具。如果机器代码也变慢,则加分。
  • 我觉得int (&amp;b)[3]: a 还是太可读了。你有什么想法让它更难读吗?
  • 使用 I3 = int[3]; for(I3 &b: a) { // 当我看起来像 1 时,这里看起来更糟。

标签: c++ arrays for-loop auto


【解决方案1】:

如果你有这样的数组

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 &amp;。但是根据 C++ 标准,您不能声明引用数组。

来自 C++ 标准(8.3.4 数组)

1 在声明 T D 中,其中 D 的形式为

D1 [ constant-expressionopt] attribute-specifier-seqopt

并且声明 T D1 中标识符的类型是 “derived-declarator-type-list T”,然后是 D 的标识符的类型 是数组类型;如果 D 的标识符的类型包含 auto 类型说明符,程序格式错误。 T 称为数组 元素类型;此类型不应是引用类型,(可能 cvqualified) 类型 void,函数类型或抽象类 输入....

【讨论】:

    【解决方案2】:

    int &amp;(b[3]) 等价于int &amp; b[3],即一个int的引用数组,其长度为3。这与数组int a[3][3]中元素的类型不对应。

    数组int a[3][3] 中的元素属于int[3] 类型,即长度为3 的int 数组。通过将 b 声明为 int(&amp;b)[3],您声明了对此类类型的引用。

    【讨论】:

      猜你喜欢
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2021-06-09
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-28
      相关资源
      最近更新 更多