for (auto o : objects)
will create mentioned copies, as it uses value semantics to get objects. You could use auto& o
to avoid this.
However, this won't work if dereferencing the iterator (which is done automatically by the range for
) returns some proxy object (in general: returns by value). An example may be std::vector<bool>
which uses such "proxy reference".
Then, this will not work:
std::vector<bool> vec;
for (auto& v : vec) // fail
{
...
}
because you cannot bind rvalue reference to non-const lvalue reference. Thus, you can use universal reference to fix this:
std::vector<bool> vec;
for (auto&& v : vec) // ok
{
...
}
In the example you posted, vector
holds pointers to objects, so there is no practical difference - if you do not want to modify the content (and thus, do not need to fetch the pointers by reference), using value is perfectly fine, as copying pointer only causes its value to be copied, not the pointee. So there is no real gain. Using rvalue reference has also no advantage, except it correctly propagates object const
-ness and is more bullet-proof if you change the type of the elements vector stores (it will still give you proper type, no matter if *iterator
returns const/non-const lvalue/rvalue reference).
Update: Actually, I have just found similar question, that was answered with almost the same example as I provided. Link.