I'm wondering what's the difference between for (auto& i : v)
and for (auto&& i : v)
in a range-based for loop like in this code:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {0, 1, 2, 3, 4, 5};
std::cout << "Initial values: ";
for (auto i : v) // Prints the initial values
std::cout << i << ' ';
std::cout << '\n';
for (auto i : v) // Doesn't modify v because i is a copy of each value
std::cout << ++i << ' ';
std::cout << '\n';
for (auto& i : v) // Modifies v because i is a reference
std::cout << ++i << ' ';
std::cout << '\n';
for (auto&& i : v) // Modifies v because i is a rvalue reference (Am I right?)
std::cout << ++i << ' ';
std::cout << '\n';
for (const auto &i : v) // Wouldn't compile without the /**/ because i is const
std::cout << /*++*/i << ' ';
std::cout << '\n';
}
The output:
Initial values: 0 1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6
2 3 4 5 6 7
2 3 4 5 6 7
Both seem to do the same thing here but I'd like to know what's the difference between for (auto& i : v)
and for (auto&& i : v)
in this code.
auto
uses template argument deduction rules. Soauto
by itself deduces the type by value,auto&
deduces by reference, andauto&&
is not an rvalue reference but rather uses reference collapsing rules to deduce the type. – Podagraauto&
is an lvalue-reference so it requires an lvalue for its initializer. The elements of the vector can be iterated over as lvalues, so it works. It's also useful when you want to prevent copying each element. This video should explain everything else - vimeo.com/97344493 – Podagraauto
would copy the object toi
(already knew this one). And there's no difference between&
and&&
in this case because there aren'trvalue
s, onlylvalue
s. Is this right? – Klugauto
by itself will allow a move. And it can only bind toauto&&
because rvalues cannot bind to lvalue-references. – Podagrastd::initializer_list
? – Klugstd::vector<bool>
is the most notorious example. – Ismastd::vector<bool>
has. It can't just be done automatically, even if you dofor (auto& x : {1, 2, 3})
the elements are still iterated over as lvalues. – Podagra