Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Move constructor is automatic generated even a member doesn't have a move constructor?

Quoted from C++ Primer

if we explicitly ask the compiler to generate a move operation by using = default, and the compiler is unable to move all the members, then the move operation will be defined as deleted

the move constructor is defined as deleted if the class has a member that defines its own copy constructor but does not also define a move constructor, or if the class has a member that doesn’t define its own copy operations and for which the compiler is unable to synthesize a move constructor

Some code seems to violate this rule:

#include <utility>
#include <iostream>

struct X {
    X() = default;
    X(const X&) { std::cout << "X(const X&)" << std::endl; }
    int i;
};

struct hasX {
    hasX() = default;
    hasX(const hasX &) = delete;
    hasX(hasX &&) = default;
    X mem;
};


int main()
{
    hasX hx, hx2 = std::move(hx);  //output is X(const X&)
}

X doesn't define move constructor and compiler can't synthesize one for it.

According to the rule above, hasX's move constructor is deleted.

However, because hasX's copy constructor is deleted, hx2 = std::move(hx) must call move constructor to output "X(const X&)", which shows hasX's move constructor is defined and it use X's copy constructor to "move". This seems to violate the rule above.

So, is't defined in C++ standard or just a compiler implementation?

Compiler I tested: VS2015 and a online compiler

Thank you for help!

like image 557
Andy Guo Avatar asked Oct 18 '22 10:10

Andy Guo


1 Answers

Your book seems to be wrong. Copying is a valid move operation so as long as the member has a copy constructor in the form of const type&, so it can bind to rvalues, the move operation will fall back to a copy.

In your example

hasX(hasX &&) = default;

Can be replaced with

hasX(hasX &&rhs) : mem(std::move(rhs.mem)) {}

as that is what the default does and it will compile just fine.

like image 79
NathanOliver Avatar answered Oct 21 '22 05:10

NathanOliver