从rvalue对象返回成员

Lea*_*rer 9 c++ rvalue move-semantics

让我们采取两个结构/类

struct C1{
  C1(){};
  C1(C1&){std::cout<<"copy"<<std::endl;}
  C1(C1&&){std::cout<<"move"<<std::endl;}};

struct C2{
  C1 c;
  C2(){};
  C1 get1(){return c;}
  C1 get2(){return std::move(c);}};
Run Code Online (Sandbox Code Playgroud)

然后

C1 a1=C2().c;
C1 a2=C2().get1();
C1 a3=C2().get2();
Run Code Online (Sandbox Code Playgroud)

输出是

move
copy
move
Run Code Online (Sandbox Code Playgroud)

我们知道rvalues的成员本身就是rvalues.这就是为什么使用a1,调用移动构造函数.为什么,在a2的情况下调用复制构造函数.我们从函数返回一个rvalue.

换句话说,std :: move强制转换为右值.但是,作为一个rvalue的成员,c,已经是一个rvalue.为什么a2和a3的行为之间存在差异?

Joh*_*erg 7

好问题.沉闷的答案是,C++规范中没有任何规则表明从这样的垂死对象中返回一个成员会自动移动它.

您可能对所谓的rvalue引用感兴趣.它让你重载&&,&这样你就可以手动实现你期望的行为:

struct C2{
  C1 c;
  C2(){};
  C1 get1() & { std::cout << "&" << std::endl; return c;}
  C1 get1() && { std::cout << "&&" << std::endl; return std::move(c);}
  C1 get2(){return std::move(c);}
};
Run Code Online (Sandbox Code Playgroud)

现在

C1 a2=C2().get1();
Run Code Online (Sandbox Code Playgroud)

版画

&&
move
Run Code Online (Sandbox Code Playgroud)

很酷,但非常罕见.

有关: