Подтвердить что ты не робот

Почему оператор, основанный на диапазоне, принимает диапазон с помощью auto &&?

Оператор 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&&.

4b9b3361

Ответ 1

Не было бы auto & хватает?

Нет, не будет. Это не позволило бы использовать выражение r-value, которое вычисляет диапазон. auto&& используется, потому что он может связываться с выражением l-value или выражением r-value. Поэтому вам не нужно вставлять диапазон в переменную, чтобы она работала.

Или, иначе говоря, это было бы невозможно:

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

Не было бы const auto&?

Нет, не будет. A const std::vector возвращает только const_iterator в его содержимое. Если вы хотите выполнить обход не const по содержимому, это не поможет.