返回右值 - 这段代码出了什么问题?

时间:2015-08-10 16:29:09

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

我遇到了以下代码段

std::string&& test()
{
    std::string m="Hello";
    return (std::move(m));
}

int main()
{
     std::string&& m = test();
}

我理解上面的代码不正确且不安全,但我不确定原因。 到目前为止,这是我对代码的理解。在函数test

  1. 在堆栈上创建了一个名为std::string的本地m变量。

  2. 然后返回此字符串,但不是复制,而是将其内容移动到临时字符串。此时,函数test结束调用变量m的析构函数(其内容已移至临时值)

  3. 现在临时绑定到右值引用m。根据我的理解,一个临时的将保持活着,直到它的绑定对象存在并且在范围内。

  4. 有人可以告诉我哪里可能出错吗?为什么上面的代码不安全?

1 个答案:

答案 0 :(得分:6)

右值引用仍然是引用,您的代码不正确的原因与下面显示的函数相同

std::string& test()
{
    std::string m="Hello";
    return m;
}

在这两种情况下,该函数都返回对局部变量的引用。 std::move除了将m投射到string&&之外不执行任何操作,因此没有临时创建的m main然后绑定到。{1}}。当test退出时,本地变量将被销毁,m是一个悬空引用。

要修复代码,请将返回类型从string&&更改为string

std::string test()
{
    std::string m="Hello";
    return m;   // std::move is redundant, string will be moved automatically
}

int main()
{
     std::string&& m = test();
}

现在m中的main可以绑定到test的返回值,lifetime of that is extended可以绑定m的返回值。