Most answers, including this one, point out that std::move
is not meant to be used in self-assignment.
I do, however, see the Possible Implementation of accumulate
in official reference via self move assignment:
template<class InputIt, class T>
constexpr // since C++20
T accumulate(InputIt first, InputIt last, T init)
{
for (; first != last; ++first) {
init = std::move(init) + *first; // std::move since C++20
}
return init;
}
Is it safe only since C++20? What is happening internally?
The EXP63-CPP states that:
it should be assumed that the only operations that may be safely performed on a moved-from object instance are reinitialization through assignment into the object or terminating the lifetime of the object by invoking its destructor
Looks like reinitialization is completely legal.
This is not a self-assignment.
A self-assignment would be init = std::move(init);
, and you have init = std::move(init) + *first;
.