移动构造函数和std :: move混淆

All*_*nzi 7 c++ move rvalue-reference c++11

我正在阅读有关std::move移动构造函数和移动赋值运算符的内容.说实话,我现在得到的只是困惑.现在我有一节课:

class A{
  public:
    int key;
    int value;
    A(){key = 3; value = 4;}
    //Simple move constructor
    A(A&& B){ A.key = std::move(B.key); 
              A.value = std::move(B.value);}
};
Run Code Online (Sandbox Code Playgroud)
  1. 我认为这B是一个右值参考,为什么你可以申请std::moveravlue参考的成员?
  2. 之后B.keyB.value已被移动,都已经失效,但如何B作为类的一个对象A被失效?
  3. 如果我有A a(A()),A()显然是一个rvlaue,可以A()被移动std::move,为什么?
  4. 同样,如果我有一个功能

    int add(int && z){ int x = std:move(z); int y = std:move(z); return x+y; }

如果我打电话add(5),怎么可以5移动,为什么?并且注意到z已经移动了两次,在z第一次移动之后,它已经失效,你怎么能再次移动它?

  1. 在定义foo (T && Z )(T,Z可以是任何东西)时,在定义的正文中为什么我应该使用std::move(Z)因为Z已经通过右值引用传递,何时应该使用std::move

vso*_*tco 12

你必须明白,std::move不会移动任何东西,但"标记"它的参数是一个右值引用.从技术上讲,它将类型转换为右值引用.然后,rvalue引用它被相应的移动构造函数或移动赋值运算符移动.对于仅包含具有普通移动ctors /赋值运算符的成员的对象,移动ctor /赋值运算符是微不足道的,只需复制.通常,对象的move ctor/assignment运算符调用其所有成员的move ctor/assignment运算符.

所以,每当你写作

int x = 10;
int y = std::move(x); 

在赋值的右侧y = std::move(x),您有一个类型的右值引用int&&.但是,int没有一个非平凡的移动ctor,并且rvalue被简单地复制到y,没有任何改变x.

另一方面,

string s = "some string";
string moved_s = std::move(s); // here we tell the compiler that we can "steal" the resource of s

是不同的.移动构造函数moved_s,并且"窃取"(即交换内部指针等)的资源s,因为后者是右值引用.最后,s不会包含任何元素.