In these questions (also here) there is recommendation to write code like:
for( auto&& v : arr )
But doesn't moving the data from arr into v clobber the array arr
? How can this style of loop be safe at all?
In these questions (also here) there is recommendation to write code like:
for( auto&& v : arr )
But doesn't moving the data from arr into v clobber the array arr
? How can this style of loop be safe at all?
First, auto&&
is not an rvalue reference. It is called a forwarding reference and it can either be an lvalue reference, or rvalue reference, depending on if the initializer is an lvalue or rvalue.
In this case arr
is a named object, so auto&&
is actually the same as auto&
in this case.
Lets pretend then arr
is an rvalue and auto&&
is actually an rvalue reference, you still don't have to worry. A reference is just an alias to the source object, it doesn't actually do anything to the source object. No move will happen as no move operation is taking place. All you are doing is referring to the element. You'd need code in the loop like
something = std::move(v); // move is required here, even though v is an rvalue reference
// because since it has a name, it is an lvalue
in order to move what v
is referring to.
With the loop as is, the biggest concern is that you can change the values stored in arr
since v
has non-const access to arr
. Using
for (const auto& v : arr)
lets you still accept lvalues and rvalues, but also does not allow you to modify the elements.