【问题标题】:Why the Range for in a two-dimensional Array is written in this way?为什么二维数组中的范围是这样写的?
【发布时间】:2015-12-11 17:04:42
【问题描述】:

这是来自github.com/pezy/CppPrimer 的一个小程序。

int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

// a range for to manage the iteration
for (const int(&p)[4] : ia)
    for (int q : p) cout << q << " ";
cout << endl;

只是想知道为什么这里 const int(&p)[4] 用在 for 的范围内。

我本来打算使用for(int p[4] : ia),因为我认为这样p 会变成int[4],所以无论是通过值还是通过引用,当p 中的每个元素都可以在下一行工作由q 访问。 但是当我尝试for(int p[4] : ia) 时,编译器说不能使用int* 来初始化int[]。我只是不知道为什么。

此外,我知道这段代码行不通:

int i = 10;
int *c= &i;
int &p = c;

一个引用不能用指针初始化,但是根据编译器给出的错误,似乎正好在这个范围内。

【问题讨论】:

  • 声明int(&amp;p)[4]p 声明为对四个整数数组 的引用。碰巧,ia 是一个由三个四个整数组成的数组.. 组成的数组
  • @5gon12eder 不,不是。如果您正在考虑内括号,它们是可选的:)
  • @Quentin 是的,对不起。混淆了 C 和 C++。
  • 请注意int &amp;p = c; 是错误的,因为您无法将指针分配给引用,但您可以取消引用指针以获取引用:int &amp;p = *c;hth
  • 顺便说一句,如果你不想看到奇怪的数组引用语法,你可以使用自动类型推导:for (const auto&amp; p : ia) ...

标签: c++ arrays pointers reference


【解决方案1】:

在 range-for 循环的机制中(描述为 here),发生了与此等价的事情:

int ia[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

// begin is deduced to be an int (*)[4]
auto begin = ia, end = ia + 12;

// Hence *begin is an int (&)[4]
int p[4] = *begin;

但是,无法从另一个数组复制初始化一个数组,并且代码无法编译。

您收到的错误消息是因为编译器试图将*begin(对行的引用)衰减为指向行的第一个元素的指针,但由于相同的原因而失败。

然而,工作示例以 :

结尾
const int (&p)[4] = *begin;

它用另一个相同类型的引用初始化一个引用,并添加了const。这是完全有效的。

【讨论】:

  • 谢谢。这真的很有帮助。我刚刚阅读了C++ Primer的前四章。我应该还需要很长时间才能理解copy assignment等机制。
【解决方案2】:
for(int p[4] : ia)

将尝试复制数组。这在 C++ 中是不允许的。

for(const int(&p)[4] : ia)

使用引用来迭代数组并且不复制它们的元素。而到第二个代码sn -p:

int &p = c;

pint的引用,它不能引用指向int的指针。以下是有效的:

int *&p = c; // reference to c
int &r = *c; // reference to int pointed to by c

【讨论】:

  • 谢谢。真的很有帮助。
猜你喜欢
  • 1970-01-01
  • 2021-06-03
  • 1970-01-01
  • 2012-06-24
  • 2014-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多