
Steven Watanabe wrote:
AMDG
Mathias Gaunard wrote:
If they're not real rvalues, that means casting was used. Which should then make it explicit that trying to access it later on is undefined behaviour as far as the implementation of the type is concerned.
Such a move would be much too limiting.
Your code needs to be able to assign a non-empty object to an empty one. Would you also consider it necessary to be able to assign an empty object to a non-empty one? Were some guidelines chosen by the standard committee as to what move semantics ought to do?
Consider how std::remove would be implemented (untested):
template<class Iter, class T> Iter remove(Iter begin, Iter end, const T& value) { begin = std::find(begin, end, value); Iter write_pos = begin++; for(; begin != end; ++begin) { if(*begin != value) { *write_pos++ = std::move(*begin);
Possible alternative here: destruct and construct. replace *write_pos++ = std::move(*begin); by reassign(*write_pos++, std::move(*begin)); with template<typename T1, typename T2> void reassign(T1& old, T2&& new) { old.~T1(); new(&old) T1(std::forward<T2>(new)); } A function called `reassign' (that would destroy the old object then construct the new one) could be used instead of assignment in cases where the left operand can be in a `moved' state.
} } return(write_pos); }
Anyway, I'm pretty sure that function could be purely implemented in terms of swap, which seems like a safer construct.