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.
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.
I would use auto&&
:
for (auto&& it : foo) {
// bla
}
The reason is spelt out in N3994 "Range-Based For-Loops: The Next Generation (Revision 1)" that it would better work with proxy objects (such as those coming from std::vector<bool>
).
In fact, that proposal for C++1z (supported already by Clang 3.5 SVN in -std=c++1z
mode) proposes the syntax:
// c++1z only
for (it : foo) {
// bla
}
as a short-hand for for (auto&& it : foo)
.
Update: the N3994 proposal was not voted into the C++17 working paper.
You may use:
for (auto&& it : foo){
}
auto &&
is prefered to auto &
to manage proxy iterator as for std::vector<bool>
.
In many ways this confusion is arising from the convention that's grown up over the years to bind a *
or a &
to the type as opposed to the variable.
For example int* a
is really int *a
; i.e. a
is a pointer to a value of type int
.
The same applies to references: in the case of int& a
, a
is a reference to a value of type int
.
So what you really want to do is write for (auto &it : foo)
so it
is a reference to the type inferred by auto
. Then you can use it
to manipulate the underlying vector elements. More often than not this will be written as
for (auto& it : foo)
Moving forward, you might want to use an r-value reference: for (auto&& it : foo)
which is probably the best general form.