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

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

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

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

ReaderValueclass中的moveAlloc函数原型是:

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 将右值传递给函数的根本原因是什么?错误消息说 other 是左值,而它看起来确实像右值引用。为什么不是第二种情况?

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

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

简而言之,c++将ReaderValue中的参数other视为左值,而moveAlloc中的参数other是右值。因此,当您调用 moveAlloc.

时,您必须将 ReaderValue 中的 other 转换为右值
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 所做的实际上是对右值的强制转换。

在字符串的第二个例子中:

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

通话

std::string(const string& other);

有效复制字符串,同时:

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

来电:

std::string(string&& other);

移动你的字符串