Move constructor on derived object

C++C++11Move Semantics

C++ 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(obj) rather than std::move(obj). Forward will return the proper rvalue or lvalue based on the what obj is whereas move will turn an lvalue into an rvalue.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChannel72View Question on Stackoverflow
Solution 1 - C++ChubsdadView Answer on Stackoverflow
Solution 2 - C++foobarView Answer on Stackoverflow
Solution 3 - C++jbreidingView Answer on Stackoverflow