Оператор for, основанный на диапазоне, определен в п. 6.5.5, чтобы быть эквивалентным:
{
auto && __range = range-init;
for ( auto __begin = begin-expr,
__end = end-expr;
__begin != __end;
++__begin ) {
for-range-declaration = *__begin;
statement
}
}
где range-init определяется для двух форм основанного на диапазоне for как:
for ( for-range-declaration : expression ) => ( expression )
for ( for-range-declaration : braced-init-list ) => braced-init-list
(предложение дополнительно указывает значение других подвыражений)
Почему __range задан выведенный тип auto&&? Мое понимание auto&& заключается в том, что оно полезно для сохранения исходной ценности (lvalue/rvalue) выражения, передавая ее через std::forward. Однако __range не проходит через std::forward. Он используется только при получении итераторов диапазона, как один из __range, __range.begin() или begin(__range).
Какая польза от использования "универсальной ссылки" auto&&? Не было бы auto&?
Примечание. Насколько я могу судить, предложение ничего не говорит о выборе auto&&.