返回一个右值——这段代码有什么问题?

Returning an rvalue - what is wrong with this code?

本文关键字:代码 问题 段代码 什么 一个 返回      更新时间:2023-10-16

我遇到了下面的代码片段

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的析构函数(其内容被移到temp中)

  3. 临时对象现在被绑定到右值引用m。据我所知,临时对象将一直保持活动状态,直到它的绑定对象处于活动状态并在作用域中。

谁能告诉我我可能在哪里做错了?为什么上面的代码不安全?

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

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

在这两种情况下,函数都返回对局部变量的引用。std::move除了将m转换为string&&之外没有做任何事情,因此没有创建main中的m然后绑定到的临时创建。当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();
}

现在main中的m可以绑定到test的返回值,并且它的生存期延长到与m相匹配。