Why does an explicit call to the base move constructor actually invoke the database constructor?

I am trying to call the base class move ctor explicitly through the derived class move ctor, but unexpectedly! which actually calls the copy of the ctor base class NOT the base class move ctor.

I use the std::move() function for an object to make sure that the derived ctor move is called!

The code:

 class Base { public: Base(const Base& rhs){ cout << "base copy ctor" << endl; } Base(Base&& rhs){ cout << "base move ctor" << endl; } }; class Derived : public Base { public: Derived(Derived&& rhs) : Base(rhs) { cout << "derived move ctor"; } Derived(const Derived& rhs) : Base(rhs) { cout << "derived copy ctor" << endl; } }; int main() { Derived a; Derived y = std::move(a); // invoke move ctor cin.ignore(); return 0; } 

SOFTWARE OUTPUT:

base copy ctor

derivative displacement ctor

As you can see, the base class move ctor is forgotten, as I call it?

+3
source share
3 answers

In the context of your Derived class, the rhs parameter explicitly has a name. So it must be an lvalue, it cannot be an rvalue. However, T&& only binds to r values. If you want to call the base class move constructor, you need to use this code:

 Derived(Derived&& rhs): Base(std::move(rhs)) { std::cout << "derived move ctor"; } 

This will call the Base move constructor and move the Base rhs part. Because Base knows nothing about Derived members, the Base move constructor will not move anything added by Derived .

+5
source

A constructor or any other function or method with && in its signature will have the right to be selected by the compiler if both of these conditions are preserved:

  • The data type of the expression you pass is T&& or T - i.e. T& will not be accepted
  • and in fact it should be an rvalue value. (by the value of T or T&& ) of the function.

move(rhs) satisfies both of these conditions. rhs is of the correct type, but it must actually be returned from a function (for example, move ) before it can be considered suitable for passing to a function that requires && .

+2
source

If the base class relocation constructor was used, then the derived constructor could access the relocated object. This is dangerous, so this will not happen unless you explicitly tell the compiler that you did this with an object, and it is safe to move.

+1
source