Is this
struct Example {
int a, b;
Example(int mA, int mB) : a{mA}, b{mB} { }
Example(const Example& mE) : a{mE.a}, b{mE.b} { }
Example(Example&& mE) : a{move(mE.a)}, b{move(mE.b)} { }
Example& operator=(const Example& mE) { a = mE.a; b = mE.b; return *this; }
Example& operator=(Example&& mE) { a = move(mE.a); b = move(mE.b); return *this; }
}
equivalent to this
struct Example {
int a, b;
Example(int mA, int mB) : a{mA}, b{mB} { }
Example(const Example& mE) = default;
Example(Example&& mE) = default;
Example& operator=(const Example& mE) = default;
Example& operator=(Example&& mE) = default;
}
?
apart very pathological cases ... YES.
To be more precise, you have also to considered eventual bases
Example
may have, with exact same rules. First the bases -in declaration order- then the members, always in declaration order.Yes both are the same.
But
This version will permits you to skip the body definition.
However, you have to follow some rules when you declare
explicitly-defaulted-functions
:Yes, a defaulted move constructor will perform a member-wise move of its base and members, so:
is equivalent to:
we can see this by going to the draft C++11 standard section
12.8
Copying and moving class objects paragraph 13 which says (emphasis mine going forward):and paragraph 15 which says:
Yes. Update: Well, not always. Look at this example:It prints:
http://coliru.stacked-crooked.com/a/62c0a0aaec15b0eb
You declared defaulted move constructor, but copying happens instead of moving. Why? Because if a class has even a single non-movable member then the explicitly defaulted move constructor is implicitly deleted (such a pun). So when you run
has_nonmovable d = std::move(c)
, the copy constructor is actually called, because the move constructor ofhas_nonmovable
is deleted (implicitly), it just doesn't exists (even though you explicitly declared the move constructor by expressionhas_nonmovable(has_nonmovable &&) = default
).But if the move constructor of
non_movable
was not declared at all, the move constructor would be used formovable
(and for every member that has the move constructor) and the copy constructor would be used fornonmovable
(and for every member that does not define the move constructor). See the example:It prints:
http://coliru.stacked-crooked.com/a/420cc6c80ddac407
Update: But if you comment out the line
has_nonmovable(has_nonmovable &&) = default;
, then copy will be used for both members: http://coliru.stacked-crooked.com/a/171fd0ce335327cd - prints:So probably putting
=default
everywhere still makes sense. It doesn't mean that your move expressions will always move, but it makes chances of this higher.One more update: But if comment out the line
has_nonmovable(const has_nonmovable &) = default;
either, then the result will be:So if you want to know what happens in your program, just do everything by yourself :sigh: