Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using swap to implement move assignment

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?

like image 968
Evan Teran Avatar asked Aug 26 '15 18:08

Evan Teran


1 Answers

"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.

like image 139
Aaron McDaid Avatar answered Oct 27 '22 09:10

Aaron McDaid