Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a range-based for statement take the range by auto&&?

Tags:

A range-based for statement is defined in §6.5.4 to be equivalent to:

{   auto && __range = range-init;   for ( auto __begin = begin-expr,              __end = end-expr;         __begin != __end;         ++__begin ) {     for-range-declaration = *__begin;     statement   } } 

where range-init is defined for the two forms of range-based for as:

for ( for-range-declaration : expression )         =>   ( expression ) for ( for-range-declaration : braced-init-list )   =>   braced-init-list 

(the clause further specifies the meaning of the other sub-expressions)

Why is __range given the deduced type auto&&? My understanding of auto&& is that it's useful for preserving the original valueness (lvalue/rvalue) of an expression by passing it through std::forward. However, __range isn't passed anywhere through std::forward. It's only used when getting the range iterators, as one of __range, __range.begin(), or begin(__range).

What's the benefit here of using the "universal reference" auto&&? Wouldn't auto& suffice?

Note: As far as I can tell, the proposal doesn't say anything about the choice of auto&&.

like image 224
Joseph Mansfield Avatar asked Nov 05 '12 22:11

Joseph Mansfield


People also ask

What does auto do in a for loop?

Range-based for loop in C++ Often the auto keyword is used to automatically identify the type of elements in range-expression.

How does range-based for loop work?

Range-based for loop in C++ Range-based for loop in C++ is added since C++ 11. It executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.

How does range-based for loop work C++?

C++11 introduced the ranged for loop. This for loop is specifically used with collections such as arrays and vectors. Here, the ranged for loop iterates the array num from beginning to end. The int variable var stores the value of the array element in each iteration.

Are range-based loops faster?

Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once. Then, yes, range-for may be slightly faster, since it's also easier to write there's no reason not to use it (when appropriate).


1 Answers

Wouldn't auto& suffice?

No, it wouldn't. It wouldn't allow the use of an r-value expression that computes a range. auto&& is used because it can bind to an l-value expression or an r-value expression. So you don't need to stick the range into a variable to make it work.

Or, to put it another way, this wouldn't be possible:

for(const auto &v : std::vector<int>{1, 43, 5, 2, 4}) { } 

Wouldn't const auto& suffice?

No, it wouldn't. A const std::vector will only ever return const_iterators to its contents. If you want to do a non-const traversal over the contents, that won't help.

like image 143
Nicol Bolas Avatar answered Sep 30 '22 19:09

Nicol Bolas