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

标签 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. 在堆栈上创建了一个名为 m 的本地 std::string 变量。

  2. 然后返回此字符串,但它的内容被 move 到临时文件中,而不是制作拷贝。此时函数 test 结束调用变量 m 的析构函数(其内容已移至 temp)

  3. 临时对象现在绑定(bind)到右值引用m。据我了解,临时对象将保持事件状态,直到其绑定(bind)对象处于事件状态并在范围内。

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

最佳答案

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

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

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

关于c++ - 返回一个右值——这段代码有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31924678/

相关文章:

c++ - 了解DEFER和OBSTRUCT宏

c++ - 使用可变参数测试成员函数是否存在

iterator - Rust 可以使用传递给函数的迭代器吗?

C++ 为什么在我的类中添加析构函数会使我的类无法 move ?

c++ - 如何将矩阵参数发送到 C++ 中的 main 函数

c++ - 为什么列表初始化允许从 double 值转换为浮点值?

c++ - 错误/var/tmp/kdecache 由 uid 1000 而不是 uid 0 拥有

c++ - 为什么我不断收到类的重新定义错误?

c++ - 如何声明模板类成员类型的指针/引用?

c++ - move 语义和 std::move