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

C++11 C++;11,move构造函数需要显式调用std::move,c++11,constructor,move,rvalue-reference,C++11,Constructor,Move,Rvalue Reference,案例1:我正在编写一个简单的移动构造函数: ReaderValue::ReaderValue(ReaderValue && other) { moveAlloc(other); } ReaderValue(std::string && otherString) : stringData(otherString) { } ReaderValue类中的moveAlloc函数原型是: void moveAlloc(ReaderValue &&

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

ReaderValue::ReaderValue(ReaderValue && other)
{
    moveAlloc(other);
}
ReaderValue(std::string && otherString)
 : stringData(otherString)
{
}
ReaderValue
类中的
moveAlloc
函数原型是:

void moveAlloc(ReaderValue && other);
我从gcc 4.8中得到错误:

cannot bind 'ReaderValue' lvalue to 'ReaderValue&&'
因此,我需要明确地调用此函数,以便编译:

moveAlloc(std::move(other));
案例2:现在ReaderValue有一个
std::string stringData
成员

我再做一个构造器:

ReaderValue::ReaderValue(ReaderValue && other)
{
    moveAlloc(other);
}
ReaderValue(std::string && otherString)
 : stringData(otherString)
{
}
这是可行的,我不需要
std::move
将otherString传递给stringData构造函数

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

(请不要回答关于实际实现的问题,或者我为什么需要这样做,诸如此类……这只是一个基本的语言问题)

建议您阅读本文 它会告诉你为什么

<> >总之,C++将参数<代码>其他<代码> >代码> >读数值>代码>,但参数<代码>其他<代码> <代码> MOVELULC/<代码>是一个值。因此,在调用
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);

移动字符串

可能您需要std::forward您的
other
而不是move?在这里使用forward和move有什么区别吗?但是在第二种情况下,它是否也会将
otherString
视为左值,并调用
std::string
的复制构造函数?是的,有问题吗?是的,为了提高效率,我想调用move构造函数。您想在文章的倒数第二个代码段中编写
:stringData(std::move(otherString))