我一直在使用基于范围的for循环,就像这样:
int a[] = {1, 2, 3, 4};
for(auto i : a){
cout << i;
}
(如果我错了,请在此处更正)我想i
在每次迭代开始时分配了序列容器a
中的下一个值,例如:
i = a[0]
…迭代1
i = a[1]
…迭代2
...
i = a[9]
…迭代10
我想问一下当循环控制变量是一个引用时这是如何工作的:
for(int &i : a){...}
由于引用不是在初始化时分配的,而是绑定的,绑定永远不会改变,那么i
会如何迭代a
并在给定的迭代中保存a
元素的值,但是如果在声明中除引用之外分配了引用,则就像分配原始变量一样。要更改数组元素,我们必须使用引用,我的问题是如何将单个引用绑定到不同的变量(即循环期间a
的元素),因为可以在循环内使用相同的引用变量来修改每个元素。
谢谢
答案 0 :(得分:1)
我发现了这个informative article可以为您提供帮助:
我认为本文的以下引文回答了您的问题:
在基于范围的
for
循环中,auto&
将创建对该范围中原始元素的引用(复数)。
其中还介绍了在基于范围的for循环中使用auto
的不同方式。
for (auto x : range)
这将创建范围内每个元素的副本。因此,当您要使用副本时,请使用此变体。
for (const auto x : range)
使用const auto可能表明您希望使用每个元素的不可变副本。
for (auto& x : range)
如果要修改非通用代码范围内的元素,请使用auto&。
for (const auto& x : range)
当您想要只读访问范围中的元素(即使是通用代码)时,请使用const auto&
for (auto&& x : range)
要修改通用代码范围内的元素时,请使用auto &&
for (const auto&& x : range)
此变体将仅绑定到右值,由于const,您将无法对其进行修改或移动。这使其变得没有用。因此,没有理由在const auto&上选择此变体。
for (decltype(auto) x : range) // C++14
这意味着:应用自动类型推导,但使用decltype
规则。自动剥离顶级cv限定词和引用,而decltype
保留它们。
答案 1 :(得分:0)
简单的想法类似于STL迭代器。您也可以想到类似的基于循环的迭代器方法,例如
for(auto it = a.begin(); it != a.end(); it++){ .... }
现在,对于基于范围的方法,在每次迭代中,您的引用都将移至下一个内存位置,并且可以根据需要更改对引用位置的访问。
for(int& i : a) { ... }
i
在第一次迭代时引用内存位置0xffffcbd0。
i
在第二次迭代时引用了内存位置0xffffcbd4。
...等等。
尝试使用i
打印&i
的存储位置。
for(int& i : a) {
cout<<i<<endl;
cout<<&i<<endl;
}