简体   繁体   中英

Using references as control variable in range-based for loops in c++

I have been messing with range-based for loops, like this one:

int a[] = {1, 2, 3, 4};

for(auto i : a){
    cout << i;
}

(Correct me here if I'm wrong)I suppose that i assigned at start of every iteration with the next value in sequence container a like:

i = a[0] … iteration 1

i = a[1] … iteration 2

i = a[9] … iteration 10

I wanted to ask how does this works when loop control variable is a reference:

for(int &i : a){...}

Since a reference is not assigned at initialization but binded, and the binding never changes then how does i iterates through a saving value of an element of a in a given iteration but when a reference is assigned except in the declaration it is like assigning the original variable. To change array elements we have to use reference, my question is how a single reference can be binded to different variables(ie elements of a during looping) as every element can be modified with the same reference variable inside the loop.

Thanks

I found this informative article that will help you:

I think the below quote from the article answers your question:

In the range based for loop, auto& will create references (plural) to the original elements in the range.

Also the different ways of using auto in a range-based for loop are covered in it.


for (auto x : range)

This will create a copy of each element in the range. Therefore, use this variant when you want to work with a copy.


for (const auto x : range)

The use of const auto may suggest that you want to work with an immutable copy of each element.


for (auto& x : range)

Use auto& when you want to modify elements in the range in non-generic code.


for (const auto& x : range)

Use const auto& when you want read-only access to elements in the range, even in generic code


for (auto&& x : range)

Use auto&& when you want to modify elements in the range in generic code


for (const auto&& x : range)

This variant will bind only to rvalues, which you will not be able to modify or move because of the const. This makes it less than useless. Hence, there is no reason for choosing this variant over const auto& .


for (decltype(auto) x : range) // C++14

It means: apply automatic type deduction, but use decltype rules. Whereas auto strips down top-level cv qualifiers and references, decltype preserves them.

Simple idea is similar to STL iterator. You can think a similar approach to iterator based for loop as well eg

for(auto it = a.begin(); it != a.end(); it++){ .... }

Now, for range based approach, at each iteration your reference moves to next memory location and access to referenced location can change whatever you need.

for(int& i : a) { ... } 

i references to memory location 0xffffcbd0 at first iteration.
i references to memory location 0xffffcbd4 at second iteration.

... and so on.

Try to print memory positions of i with &i .

for(int& i : a) { 
    cout<<i<<endl;
    cout<<&i<<endl;
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM