Why use && in range for?

Hi,

I ran into an example of a range for where the elements are extracted using auto&&. Why is this? Why not use auto& ? What is the difference?

The code is:

1
2
3
4
5
6
7
8
9
10
         dummy_array<int, 3> arr;
         arr.SetAt(0, 1);
         arr.SetAt(1, 2);
         arr.SetAt(2, 3);

         for (auto&& e : arr)
         {
            ::std::cout << e << ::std::endl;
         }


Debugging this, the type of e is const int& in both cases (using auto&& and using auto&), so why use auto&&? Is it to be able to get temporary elements from the array?

Regards,
Juan
I ran into an example of a range for where the elements are extracted using auto&&. Why is this? Why not use auto& ? What is the difference?

The range-based for loop is equivalent to a similar iterator-based loop:
https://timsong-cpp.github.io/cppwp/n4140/stmt.ranged#1
https://en.cppreference.com/w/cpp/language/range-for#Explanation

The difference between auto& and auto&& is relevant when elt's initializer is an rvalue expression. The canonical example involves vector<bool>, whose iterator's operator* typically returns a proxy type by value:
1
2
3
4
5
6
7
#include <vector>
int main()
{
    std::vector<bool> v{ true, false, true, false };   
    for (auto& elt: v) elt = true; // vs.
    for (auto&& elt: v) elt = true; 
}

http://coliru.stacked-crooked.com/a/493f418165dbfe4c

The first loop fails to compile, because it attempts to bind a lvalue reference to an rvalue.
Last edited on
https://blog.petrzemek.net/2016/08/17/auto-type-deduction-in-range-based-for-loops/

Use auto&& when you want to modify elements in the range in generic code (e.g. templates).

This isn't modifying elements so there's no real reason to use it here; it's not doing any harm in the code, but it is making people (such as you) wonder why it's here. That is in itself a reason to not do this; because code is meant to communicate meaning to the reader, and this code has failed at doing that.
Last edited on
Registered users can post here. Sign in or register to post.