如何在函数返回期间使用std :: string移动语义?

Edd*_*223 19 c++ move-semantics c++11

可能重复:
C++ 11 rvalues并且移动语义混乱

我认为是正确的

std::string GetLine()
{
std::string str;
std::getline(std::cin, str);
return std::move(str);
}
Run Code Online (Sandbox Code Playgroud)

但是在这个链接http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html (检查标题部分返回一个明确的右值引用功能)

这是#1谷歌搜索命中移动语义显示类似的功能签名

int&& GetInt()
{
int x = 0;
// code here
return std::move(x);
}
Run Code Online (Sandbox Code Playgroud)

从我在其他地方读到的&&表示右值引用,所以在这种情况下它返回对不存在的对象的引用.

那是哪个呢?

(是的,我知道移动一个int没有真正的好处,但问题是在第一个函数中是否使用std :: string或std :: string &&的返回类型.如果这是应该对所有类型执行的方式.)

bam*_*s53 34

您完全正确的int&& GetInt()示例是错误的,并且正在返回对被销毁对象的引用.但是,除非我错过了,否则您发布的链接实际上并未显示任何返回对局部变量的引用的代码.相反,我看到对返回的全局变量的引用,这没关系.

以下是返回时使用移动语义的方法:

std::string func()
{
    std::string rv;
    /* ... */
    return rv;
}
Run Code Online (Sandbox Code Playgroud)

std::move()返回对象时通常不应使用.这样做的原因是任何时候RVO都可以隐式允许移动,并且使用std::move()将抑制RVO.所以使用std::move()永远不会更好,往往会比正常回归更糟糕.


同样,使用std::move()可能比简单地命名要返回的变量更糟糕,因为它抑制了返回值优化.返回值优化允许将对象返回给调用者,而无需复制该对象

return具有类返回类型的函数的语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象(除函数或catch子句参数之外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作

- [class.copy] 12.8/31

但是使用std::move()可以防止返回表达式成为您要返回的对象的名称.相反,表达式更复杂,不再允许语言对其进行特殊处理.

仅命名对象的原因并不比使用更糟糕的原因std::move()是因为还有另一条规则表明表达式已经可以被视为rvalue而不需要了std::move().

当满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定,重载决策选择复制的构造函数是首先执行,好像对象是由右值指定的.

  • @mloskot对,copy-elision/RVO(n3337§12.8/ 31)不同于在某些情况下需要移动而不是副本的特殊规则(n3337§12.8/ 32).我使用RVO仅指前者. (2认同)

eq-*_*eq- 9

回答这个问题,排序:返回string.什么都不做move,而是使用(依赖)RVO:

std::string func()
{
    std::string rv;
    /* ... */
    return rv;
}
Run Code Online (Sandbox Code Playgroud)

这通常应该如何完成.您不能将(r值或非r)值引用返回临时值.