是否可以将对象移出函数? (C++11)

2024-03-24

该程序尝试将一个字符串移出函数并将其用于构造另一个字符串:

#include <iostream>
#include <string>
#include <utility>

std::string && Get_String(void);

int main(){

    std::string str{Get_String()};
    std::cout << str << std::endl;

    return 0;
}

std::string && Get_String(void){

    std::string str{"hello world"};

    return std::move(str);
}

程序可以编译,但执行时出现段错误。


这是我的理由:Get_String将创建一个本地字符串。在字符串超出范围之前,需要创建并返回该字符串的副本。该副本将用于构造 main 中的字符串。但是,如果我将字符串移出函数,则不需要进行复制。

为了尝试理解移动语义,有人可以解释为什么我正在做的事情可能没有意义。是否可以将对象移出函数?


EDIT:
如果我更改函数签名,它会正确编译并运行:

std::string && Get_String(void);

to

std::string Get_String(void);  

在这种情况下,在返回期间移动字符串是否会更有效?


鉴于这个例子,

X foo ()
{
  X x;    
  return x;
}

保证以下行为:

• If X有一个可访问的复制或移动构造函数,编译器可以 选择删除副本。这就是所谓的(命名的)返回值 优化 ((N)RVO),甚至在 C++11 之前就已指定,并且是 大多数编译器都支持。
• 否则,如果X有一个移动构造函数,x被感动了。
• 否则,如果X有一个复制构造函数,x被复制。
• 否则,将发出编译时错误。

另请注意,如果返回的对象是本地非静态对象,则返回右值引用是错误的:

X&& foo ()
{
  X x;
  return x; // ERROR: returns reference to nonexistent object
}

右值引用是一个引用,在引用本地对象时返回它意味着您 返回对不再存在的对象的引用。无论std::move()被使用 没有 事情。

std::move()并没有真正移动物体;它只会将左值转换为右值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以将对象移出函数? (C++11) 的相关文章