Is the =default move constructor equivalent to the member move constructor?
Yes. Update: Well, not always. Take a look at this example:
#include <iostream> struct nonmovable { nonmovable() = default; nonmovable(const nonmovable &) = default; nonmovable( nonmovable &&) = delete; }; struct movable { movable() = default; movable(const movable &) { std::cerr << "copy" << std::endl; } movable( movable &&) { std::cerr << "move" << std::endl; } }; struct has_nonmovable { movable a; nonmovable b; has_nonmovable() = default; has_nonmovable(const has_nonmovable &) = default; has_nonmovable( has_nonmovable &&) = default; }; int main() { has_nonmovable c; has_nonmovable d(std::move(c)); // prints copy }
This prints:
copy
http://coliru.stacked-crooked.com/a/62c0a0aaec15b0eb
You declared the default move constructor, but instead of moving, copying occurs. What for? Because, if a class has at least one fixed member, then the explicitly specified default constructor of the move is implicitly deleted (such a pun). Therefore, when you run has_nonmovable d = std::move(c) , the copy constructor is actually called because the move constructor from has_nonmovable is deleted (implicitly), it simply does not exist (even if you explicitly declared the move constructor the expression has_nonmovable(has_nonmovable &&) = default ).
But if the non_movable move non_movable not declared, the move constructor would be used for movable (and for every member that has a move constructor), and the copy constructor would be used for nonmovable (and for every member that didn't define a move constructor). See an example:
#include <iostream> struct nonmovable { nonmovable() = default; nonmovable(const nonmovable &) { std::cerr << "nonmovable::copy" << std::endl; } //nonmovable( nonmovable &&) = delete; }; struct movable { movable() = default; movable(const movable &) { std::cerr << "movable::copy" << std::endl; } movable( movable &&) { std::cerr << "movable::move" << std::endl; } }; struct has_nonmovable { movable a; nonmovable b; has_nonmovable() = default; has_nonmovable(const has_nonmovable &) = default; has_nonmovable( has_nonmovable &&) = default; }; int main() { has_nonmovable c; has_nonmovable d(std::move(c)); }
This prints:
movable::move nonmovable::copy
http://coliru.stacked-crooked.com/a/420cc6c80ddac407
Update: but if you comment out the line has_nonmovable(has_nonmovable &&) = default; , then a copy will be used for both participants: http://coliru.stacked-crooked.com/a/171fd0ce335327cd - prints:
movable::copy nonmovable::copy
So probably setting =default makes sense everywhere. This does not mean that your expressions of movement will always move, but it increases the chances of it.
Another update: But if you comment out the line has_nonmovable(const has_nonmovable &) = default; either, the result will be:
movable::move nonmovable::copy
So if you want to know what is going on in your program, just do it yourself: sigh: