What does `auto && e` do in range-based for-loops?

When and if you should use auto&& in for loops has been explained very nicely by Howard Hinnant here.

This leaves the question what x in

auto &&x = ...expr...

actually is. And it is handled as if there there were a function template definition

template <class U> void f(U&& u);

and the type of x is deduced by the same rules as u [§7.1.6.4.(7)].

This means it is not handled as a RValue Reference, but as a “Universal/Forwarding Reference” — the “Reference Collapsing Rules” apply.

This also holds for

const auto &&x = ...expr...

as the example in §7.1.6.4.(7) states, at least for const auto &x.

But, as PiotrS says in the questions comments, any qualifiers nullifies the URef-ness:

no, because neither T in template<class T> void f(const T&&) is a forwarding reference, nor const auto&& is. The fact that T&& occurs in parameter declaration does not imply it is forwarding reference. Only pure T&& with no qualifiers like const or volatile is forwarding reference, meaning it has to be template<class T> void f(T&&) or auto&&, and never const T&& or const auto&&

Leave a Comment