C++11 range based loop: get item by value or reference to const
If you don't want to change the items as well as want to avoid making copies, then auto const &
is the correct choice:
for (auto const &x : vec)
Whoever suggests you to use auto &
is wrong. Ignore them.
Here is recap:
- Choose
auto x
when you want to work with copies. - Choose
auto &x
when you want to work with original items and may modify them. - Choose
auto const &x
when you want to work with original items and will not modify them.
If you have a std::vector<int>
or std::vector<double>
, then it's just fine to use auto
(with value copy) instead of const auto&
, since copying an int
or a double
is cheap:
for (auto x : vec)
....
But if you have a std::vector<MyClass>
, where MyClass
has some non-trivial copy semantics (e.g. std::string
, some complex custom class, etc.) then I'd suggest using const auto&
to avoid deep-copies:
for (const auto & x : vec)
....
When we don't need changing
vec
items, Examples suggest to use first version.
Then they give a wrong suggestion.
Why they don't suggest something which const references
Because they give a wrong suggestion :-) What you mention is correct. If you only want to observe an object, there is no need to create a copy, and there is no need to have a non-const
reference to it.
EDIT:
I see the references you link all provide examples of iterating over a range of int
values or some other fundamental data type. In that case, since copying an int
is not expensive, creating a copy is basically equivalent to (if not more efficient than) having an observing const &
.
This is, however, not the case in general for user-defined types. UDTs may be expensive to copy, and if you do not have a reason for creating a copy (such as modifying the retrieved object without altering the original one), then it is preferable to use a const &
.