Suppose I have foo
which is a populated std::vector<double>
.
I need to operate on the elements of this vector. I'm motivated to write
for (auto it : foo){ /*ToDo - Operate on 'it'*/ }
But it appears that this will not write back to foo
since it
is a value type: a deep copy of the vector element has been taken.
Can I give some guidance to auto
to make it
a reference type? Then I could operate directly on it
.
I suspect I'm missing some trivial syntax.
Range-based for loop in C++ Often the auto keyword is used to automatically identify the type of elements in range-expression.
C++11 introduced the ranged for loop. This for loop is specifically used with collections such as arrays and vectors. Here, the ranged for loop iterates the array num from beginning to end. The int variable var stores the value of the array element in each iteration.
Use the range-based for statement to construct loops that must execute through a range, which is defined as anything that you can iterate through—for example, std::vector , or any other C++ Standard Library sequence whose range is defined by a begin() and end() .
Range-based for loop (since C++11) Executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.
A minimal auto
reference
The loop can be declared as follows:
for (auto& it : foo) { // ^ the additional & is needed /*ToDo - Operate on 'it'*/ }
This will allow it
to be a reference to each element in foo
.
There is some debate as to the "canonical form" of these loops, but the auto&
should do the trick in this case.
General auto
reference
In a more general sense (outside the specifics of the container), the following loop works (and may well be preferable).
for (auto&& it : container) { // ^ && used here }
The auto&&
allows for bindings to lvalues and rvalues. When used in a generic or general (e.g. template situation) this form may strike the desired balance (i.e. references, copies, prvalue/xvalue returns (e.g. proxy objects) etc.).
Favour the general auto&&
, but if you have to be specific about the form, then use a more specific variation (e.g. auto
, auto const&
etc.).
Why is auto&&
better?
As noted in other answers here and the comments. Why is auto&&
better? Simply it will do what you think it should in most cases, see this proposal and its update.
As always, Scott Meyers' blog about this also makes for a good read.
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