galinette
galinette

Reputation: 9292

C++11 , move constructor requiring to call std::move explicitely

Case 1 :I am writing a simple move constructor:

ReaderValue::ReaderValue(ReaderValue && other)
{
    moveAlloc(other);
}

The moveAlloc function prototype in the ReaderValue class is:

void moveAlloc(ReaderValue && other);

I get the error from gcc 4.8:

cannot bind 'ReaderValue' lvalue to 'ReaderValue&&'

So I need to call explicitely this in order to compile:

moveAlloc(std::move(other));

Case 2 : Now ReaderValue has a std::string stringData member

I make another constructor:

ReaderValue(std::string && otherString)
 : stringData(otherString)
{
}

This works, I do not need std::move to pass otherString to the stringData constructor

Question : What is the fundamental reason why I need to explicitely call std::move to pass the rvalue to a function in the first case? The error message says other is a lvalue, whereas it does look like a rvalue reference. Why not in the second case?

(Please don't reply about the actual implementation, or why do I need to do this, blah blah... That's only a fundamental language question)

Upvotes: 0

Views: 127

Answers (2)

dau_sama
dau_sama

Reputation: 4357

ReaderValue::ReaderValue(ReaderValue && other)
{
    //other here is a lvalue(has a name) referring to a rvalue
    //move alloc however takes a rvalue
    moveAlloc(other);
}

that is why you have to cast your lvalue to a rvalue explicitely

moveAlloc(std::move(other)); //other now is a rvalue

please note that all std::move does is effectively a cast to rvalue.

In the second example with the string:

 ReaderValue(std::string && otherString)
 : stringData(otherString)
{ }

calls

std::string(const string& other);

effectively copying the string, while:

ReaderValue(std::string && otherString)
: stringData(std::move(otherString))
{ }

calls:

std::string(string&& other);

moving your string

Upvotes: 1

frank.lin
frank.lin

Reputation: 1694

Suggest you to read this http://thbecker.net/articles/rvalue_references/section_05.html it'll will tell you why.

In a short, c++ regards parameter other in ReaderValue as a lvalue, but the parameter other in moveAlloc is a rvalue. So you have to convert other in ReaderValue to a rvalue when you call moveAlloc.

Upvotes: 1

Related Questions