
On Sep 7, 2009, at 3:26 PM, Christopher Jefferson wrote:
On 7 Sep 2009, at 20:08, Jeffrey Hellrung wrote:
Howard Hinnant wrote:
Using an experimental C++0x compiler and library (you might can do this experiment g++-4.4, I'm not sure) I make this substitution and indeed, I get the same output (remove all of the *.dat files prior to each run). This experimental library has: template <class _Tp, class _Allocator> inline vector<_Tp, _Allocator>& vector<_Tp, _Allocator>::operator=(vector&& __x) { clear(); swap(__x); return *this; }
Perhaps a dumb question, but isn't the above incorrect under self- assigment (x = move(x))? Is there a "standard way" or "recommended guideline" for handling self-assignment in the move assignment operator, or is this a nonissue?
I'm actually not 100% positive what the intended semantics of x = move(x) are, but clearly as a QOI issue it should behave.
Most people put:
if(&__x != this)
or something similar in normal assignment operators, adding it also to all move operators seems very sensible.
My hope has been to make x = move(x) undefined behavior. Rationale: The move assignment operator should be fast enough that an extra if- test may adversely impact performance (above the noise level). The philosophy has been that code should be able to assume that if given an rvalue, then it /really/ is an rvalue. And if the client lied by moving an lvalue, then it is up to the client to make sure that lie is really safe. And if the rhs /really is/ an rvalue, then self assignment is impossible. After all, one of the primary motivations for move semantics is performance. So I'd really like it to be as fast as possible. The slower it is, the less important it is. The draft standard could probably use a statement to that effect. Currently the closest thing in there with regards to this issue is [container.requirements.general]/12:
An object bound to an rvalue reference parameter of a member function of a container shall not be an element of that container; no diagnostic required.
-Howard