Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why a copy is performed in move assignment implementation? #2

Closed
zerkms opened this issue Oct 29, 2015 · 8 comments
Closed

Why a copy is performed in move assignment implementation? #2

zerkms opened this issue Oct 29, 2015 · 8 comments
Labels

Comments

@zerkms
Copy link

zerkms commented Oct 29, 2015

In the following article https://rmf.io/cxx11/rule-of-zero/ you implemented a move assignment in this way:

module& operator=(module&& that) {
    module copy { std::move(that) };
    std::swap(handle, copy.handle);
    return *this;
}

What purpose does the copying here serve? Could it not just be std::swap(handle, that.handle);?

Thanks

@brettwhiteman
Copy link

If it were just std::swap(handle, that.handle); then the original this->handle will only be freed when that is destroyed. Ideally it should be freed when the move is actually performed.

Is this correct?

Edit: this illustrates the difference http://ideone.com/IqXSRy

@rmartinho
Copy link
Owner

Yes, exactly. When you use assignment you fully expect the left hand side to be lost, not given to the right hand side. Giving op= the same semantics as swap is confusing, and should not be done, IMO.

@zerkms
Copy link
Author

zerkms commented Oct 29, 2015

Cool, thanks.

@gnzlbg
Copy link

gnzlbg commented Oct 29, 2015

I end up writing move assignment as just:

module& operator=(module that) {
    std::swap(handle, that.handle);
    return *this;
}

@zerkms
Copy link
Author

zerkms commented Oct 29, 2015

@gnzlbg would it work if the module is not copyable? Would it even be treated as a move assignment? (its signature does not look so)

@gnzlbg
Copy link

gnzlbg commented Oct 29, 2015

@gnzlbg would it work if the module is not copyable? Would it even be treated as a move assignment? (its signature does not look so)

Sure. If the module is only movable then module& operator=(module) will only work on rvalues and they will be moved. operator= and the constructors are just functions. They are called special member functions because the compiler might generate them for you but that is as special as they get. Overloading resolution works as usual.

@brettwhiteman
Copy link

@gnzlbg It's not clear to someone else looking at your code that it's a move assignment since it doesn't follow the usual signature.

@gnzlbg
Copy link

gnzlbg commented Oct 30, 2015

@developerbmw if you just need to make a type copy/move assignable fast, and the type already has copy/move constructors, this is a not-very-efficient but very simple solution that allows you to reuse all of the copy/move constructors code.

Readers that just want to use the type are typically only interested on knowing if the type is at least SemiRegular (which requires MoveAssignable). This is really easy to check: just require or static_assert on it.

If the reader is interested in knowing exactly how the type works and doesn't know this idiom you make a very good point, but arguably the same argument can be made about other idioms like copy-and-swap, and a similar argument can be made about any type that has user defined special member functions (the reader has to work through them anyways).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants