In GitHub repositories there are not few examples where the range-expression in range-based for loop is surrounded in std::move, e.g. in pytorch:
...
outputs = (*call_op)(schema, std::move(inputs), std::move(outputs));
for (auto&& output : std::move(outputs)) {
torch::jit::push(*stack, std::move(output));
}
Since output here just iterates over the elements of std::move(outputs) and we have std::move(output) inside loop body, does for-loop is really different from the variant without the first std::move:
for (auto&& output : outputs) {
torch::jit::push(*stack, std::move(output));
}
and if yes, can the difference be observed with some classes from the standard library or only with some specially designed ones?
The range-based
forstatement is defined by translation:where
begin-exprandend-expreither arerange.begin()andrange.end(), or arebegin(range)andend(range), dependent on whether lookup for the former succeeds.This means that within
begin-exprandend-expr,rangeis an lvalue, regardless of whetherfor-range-initializeris an lvalue or an xvalue (or even a prvalue).So wrapping a
for-range-initializerinstd::move()will not have any effect on program behavior.