Есть ли техническая причина, по которой цикл for на основе диапазона не определяет, зацикливается ли он на rvalue?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Есть ли техническая причина, по которой цикл for на основе диапазона не определяет, зацикливается ли он на rvalue?

Сообщение Anonymous »

Причина вопроса в том, что я видел такой код:

Код: Выделить всё

auto fun(std::vector&& v) {
std::vector w;
for (auto&& e : v /* not an rvalue, but keep reading */) {
w.push_back(std::move(e));
}
// do stuff with w
}
который помечен инструментами статического анализа как ошибочный, поскольку ссылка пересылки e имеет формат std::moved вместо std::forwarded.
С другой стороны, v наверняка привязывается к значению prvalue или xvalue (которое клиент знает или хочет с удовольствием рассматривать как временный), поскольку его тип является ссылкой rvalue. Да, я вижу, что в теле функции никоим образом не указано, что v нельзя использовать после цикла for, но это только навело бы меня на мысль, что мне следует изменить
  • Код: Выделить всё

    for (auto&& e : v)
    для for (auto&& e : std::move(v)),
  • и auto&& для E&&, предполагая что-то вроде использования E = std::decay_t::value_type;.
Насколько далеко как я понял, первый пункт не дал того эффекта, на который я рассчитывал. Фактически, std::move, похоже, не имеет никакого эффекта в отношении for. В свою очередь, e продолжает инициализироваться из значения lvalue (по крайней мере, если частый случай, когда оператор[] возвращает ссылку на тип v), а второй момент просто вызывает ошибку компиляции.
В качестве дополнительной ссылки примечание ¹ из этого ответа гласит (со ссылкой на диапазон- циклы)

Вы не можете определить, выполняете ли вы итерацию по временному (или другому r-значению)

что, похоже, подтверждает, что я просто не могу этого сделать.
Но глядя на то, как работает диапазон-

Код: Выделить всё

forЦикл 
очищен от сахара, что было бы неправильным при замене range-declaration = *__begin; на range-declaration = std::move(*__begin);, когда

Код: Выделить всё

range-expression
является значением r?

Подробнее здесь: https://stackoverflow.com/questions/747 ... hether-its
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»