I found this code in Bjarne Stroustrup's The C++ programming language (4. edition).
In this example, as far as my understanding goes, we increment x without copying the value of v into x. My question is, that why do we reference to x, and not to v?
I tried understanding the problem by breaking it down and writing it down onto a paper, that what would happen in the memory simplified, but I do not get it.
void increment()
{
int v[]={0,1,2,3,4,5,6,7,8,9};
for(auto& x : v)
{
++x;
}
}
This is a good beginner question. Have a look at what cppreference has on range-based for loops. Because v
is an array type, this above snippet expands to
{
auto && __range = v;
for (auto __begin = __range, __end = (__range + bound);
__begin != __end; ++__begin)
{
auto& x = *__begin;
++x
}
}
where "bound
is the number of elements in the array (if the array has unknown size or is of an incomplete type, the program is ill-formed)" [citation from the above link].
We can see, that the machinery behind such a range-based for loop makes sure that we act on an lvalue reference to v
here: auto && __range = v
uses type deduction with a forwarding reference, which does the right thing.
In short, with the auto& x
part in the loop, you control what is being initialized when the iterators pointing into the range are dereferenced (*__begin
). For example, with auto& x
you get a reference to an element in the range (which you can change, affecting the range), with const auto& x
, you get a const
-qualified reference to an element in the range (which you can't mutate). You obtain copies of each element with auto x
, and const
-qualified copies of each element with const auto x
, but the latter is hardly useful.
Because the for
loop is changing the array elements, so you want a reference to each element in order to increment them.
If you incorrectly had:
for(auto x : v)
{
++x;
}
nothing in v
would change because x
is a copy of the array elements.
Making it:
for(auto x : &v)
{
++x;
}
doesn't compile because &v
is the address of the array (not the address of the first element in the array as v
is) and is invalid in range expressions.
But using:
for(auto& x : v)
{
++x;
}
now makes x
a reference to elements in v
and can therefore change them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With