Something occurred to me which I think it completely reasonable, but I'd like people's opinion on it in case I'm just completely missing something. So firstly, my understanding of T& operator=(T&& rhs)
is that we don't care what the contents of rhs
are when we are done, just that the contents have been moved into this
and that rhs
is safely destructable.
That being said, a common exception safe implementation of the copy-assignment operator, assuming that swaps are cheap, looks like this:
T& operator=(const T& rhs) {
if(this != &rhs) {
T(rhs).swap(*this);
}
return *this;
}
So one natural way to implement the move-assignment operator would be like this:
T& operator=(T&& rhs) {
if(this != &rhs) {
T(std::move(rhs)).swap(*this);
}
return *this;
}
But then it occured to me, rhs
doesn't have to be empty! So, why not just do a plain swap
?
T& operator=(T&& rhs) {
rhs.swap(*this); // is this good enough?
return *this;
}
I think that this satisfies what the move-assignment operator needs to do... but like I said, this just occurred to me, so I assume that it's possible that I'm missing something.
The only "downside" that I can think of is that things owned by this
will potentially live longer using the plain swap when compared to the version which does a move-construct/swap.
Thoughts?
"what the move-assignment operator needs to do"
I always find the best way to treat a &&
variable is to say that "nobody cares what state I leave this variable in". You may move from it. You may copy from it. You may swap into it. There are many more things you can do.
Your code is correct. The &&
can be left in any state whatsoever (as long as it is destructible).
The object will be destructed sooner or later (probably sooner) and the implementer should be aware of this. This is important if the destructor will delete
raw pointers, which would lead to double-deletion if the same raw pointer is in multiple objects.