让我们采用两个结构/类
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);}};
比
C1 a1=C2().c;
C1 a2=C2().get1();
C1 a3=C2().get2();
输出是
move
copy
move
问题
我们知道右值的成员本身就是右值。这就是为什么在 a1 中调用 move 构造函数的原因。为什么比,在a2的情况下调用了复制构造函数。我们从函数返回一个右值。
换句话说,std::move 转换为右值。但是,作为右值的成员,c 已经是一个右值。为什么 a2 和 a3 的行为会有所不同?
最佳答案
好问题。无聊的答案是,C++ 规范中没有任何规则规定从像这样的垂死对象返回成员会自动 move 它。
您可能对所谓的右值引用感兴趣。它让你重载 &&
和 &
这样你就可以手动实现你期望的行为:
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);}
};
现在
C1 a2=C2().get1();
打印
&&
move
很酷,但很少见。
相关:
关于c++ - 从右值对象返回一个成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48490519/