C ++ 11,移动构造函数需要显式调用std :: move

时间:2015-01-22 09:21:01

标签: c++11 constructor move rvalue-reference

案例1 :我正在编写一个简单的移动构造函数:

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

moveAlloc类中的ReaderValue函数原型是:

void moveAlloc(ReaderValue && other);

我从gcc 4.8中得到错误:

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

所以我需要明确地调用它来编译:

moveAlloc(std::move(other));

案例2 :现在,ReaderValue有一个std::string stringData成员

我创建另一个构造函数:

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

这有效,我不需要std::move将otherString传递给stringData构造函数

问题:在第一种情况下,我需要明确地调用std :: move将rvalue传递给函数的根本原因是什么?错误消息说其他是左值,而它看起来像右值引用。为什么不在第二种情况下?

(请不要回复实际的实施,或者为什么我需要这样做,等等......这只是一个基本的语言问题)

2 个答案:

答案 0 :(得分:1)

建议你阅读http://thbecker.net/articles/rvalue_references/section_05.html 它会告诉你原因。

简而言之,c {{{{{}} other中的参数ReaderValue作为左值,但other中的参数moveAlloc是右值。因此,当您致电other时,您必须将ReaderValue中的moveAlloc转换为右值。

答案 1 :(得分:1)

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

这就是为什么你必须将你的左值明确地转换为右值

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

请注意,所有std :: move确实是对rvalue的强制转换。

在带字符串的第二个示例中:

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

来电

std::string(const string& other);

有效地复制字符串,同时:

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

调用:

std::string(string&& other);

移动你的字符串