Диапазон на основе for
заявление определено в §6.5.4, чтобы быть эквивалентным:
{
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&&
,
Не будет авто& хватает?
Нет, не будет. Это не позволило бы использовать выражение r-значения это вычисляет диапазон. auto&&
используется, потому что он может связываться с выражением l-значения или же выражение r-значения. Поэтому вам не нужно вставлять диапазон в переменную, чтобы он работал.
Или, другими словами, это было бы невозможно:
for(const auto &v : std::vector<int>{1, 43, 5, 2, 4})
{
}
не было бы
const auto&
хватает?
Нет, не будет. const std::vector
вернется только когда-либо const_iterator
с его содержанием. Если вы хотите сделать неconst
обход содержимого, это не поможет.
Других решений пока нет …