Move constructor on derived object
C++C++11Move SemanticsC++ Problem Overview
When you have a derived object with a move constructor, and the base object also has move semantics, what is the proper way to call the base object move constructor from the derived object move constructor?
I tried the most obvious thing first:
Derived(Derived&& rval) : Base(rval)
{ }
However, this seems to end up calling the Base object's copy constructor. Then I tried explicitly using std::move
here, like this:
Derived(Derived&& rval) : Base(std::move(rval))
{ }
This worked, but I'm confused why it's necessary. I thought std::move
merely returns an rvalue reference. But since in this example rval
is already an rvalue reference, the call to std::move
should be superfluous. But if I don't use std::move
here, it just calls the copy constructor. So why is the call to std::move
necessary?
C++ Solutions
Solution 1 - C++
rval
is not a Rvalue. It is an Lvalue inside the body of the move constructor. That's why we have to explicitly invoke std::move
.
Refer this. The important note is
> Note above that the argument x is > treated as an lvalue internal to the > move functions, even though it is > declared as an rvalue reference > parameter. That's why it is necessary > to say move(x) instead of just x when > passing down to the base class. This > is a key safety feature of move > semantics designed to prevent > accidently moving twice from some > named variable. All moves occur only > from rvalues, or with an explicit cast > to rvalue such as using std::move. If > you have a name for the variable, it > is an lvalue.
Solution 2 - C++
Named R-value references are treated as L-value.
So we need std::move
to convert it to R-Value.
Solution 3 - C++
You really should use std::forward