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
Topic archived. No new replies allowed.