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

Что делает `auto && e` в диапазонах for-loops?

Предполагая мое текущее правило, когда программирование с помощью циклов на основе диапазонов говорит

Используйте for(auto const &e :...) или for(auto &e:...), когда это возможно, над for(auto a: ...).

Я основываю это на собственном опыте и на этом вопросе, например.

Но после прочтения новой краткой для петель, интересно, не следует ли заменить мой & в моем правиле на &&? Как написано здесь, это выглядит как Универсальные ссылки Мейерса.

Итак, я спрашиваю себя, должно ли мое новое правило быть

Используйте for(auto const &&e :...) или for(auto &&e:...), когда это возможно...

или это не всегда работает и, следовательно, должно быть довольно сложным.

Проверьте, возможно ли for(auto const &&e :...) или for(auto &&e:...), затем рассмотрите for(auto const &e :...) или for(auto &e:...) и только при необходимости не используйте ссылки.

4b9b3361

Ответ 1

Когда и если вы должны использовать auto&& in для циклов, здесь было очень хорошо объяснено Howard Hinnant.

Это оставляет вопрос о том, что x в

auto &&x = ...expr...

на самом деле есть. И обрабатывается так, как если бы там было определение шаблона функции

template <class U> void f(const U& u);

а тип x выводится теми же телами, что и u [§7.1.6.4. (7)].

Это означает, что не обрабатывается как ссылка на RValue, но как "Универсальная/переадресация" - " Правила привязки ссылок".

Это также справедливо для

const auto &&x = ...expr...

как пример в п. 7.1.6.4. (7), как минимум, для const auto &x.

Но, как говорит PiotrS в комментариях к комментариям, любые квалификаторы аннулируют URef-ness:

нет, потому что ни T в template<class T> void f(const T&&) не является ссылкой для пересылки, ни const auto&&. Тот факт, что T&& происходит в объявлении параметра, не означает, что он пересылает ссылку. Только чистый T&& без квалификаторов, таких как const или volatile, пересылает ссылку, то есть он должен быть template<class T> void f(T&&) или auto&&, а никогда const T&& или const auto&&