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&&
.
Range-based for loop in C++ Often the auto keyword is used to automatically identify the type of elements in range-expression.
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.
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.
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).
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_iterator
s to its contents. If you want to do a non-const
traversal over the contents, that won't help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With