移动构造函数和std :: move混乱 [英] move constructor and std::move confusion

查看:129
本文介绍了移动构造函数和std :: move混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 std::move ,移动构造函数并移动赋值操作员. 老实说,我现在所得到的只是混乱.现在我上了一堂课:

I am reading about the std::move, move constructor and move assignment operator. To be honest, all I got now is confusion. Now I have a class:

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);}
};

  1. 我以为B是右值引用,为什么您可以将std::move应用于ravlue引用的成员?
  2. 在移动了B.keyB.value之后,它们都已失效,但是作为类A的对象的B如何失效?
  3. 如果我有A a(A())A()显然是rvlaue,std::move可以移动A()怎么办?为什么?
  4. 类似地,如果我有功能

  1. I thought B is an rvalue reference, why you can apply std::move to an ravlue reference's member?
  2. After B.key and B.value have been moved, both have been invalidated, but how B as an object of class A gets invalidated?
  3. What if I have A a(A()), A() is apparently an rvlaue, can A() be moved by std::move and why?
  4. Similarly, if I have a function

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

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

如果我呼叫add(5),怎么移动5?为什么? 并注意z已被移动两次,第一次z被移动后,它已失效,如何再次移动它?

What if I call add(5), how can 5 be moved and why? And notice that z has been moved twice, after z has been moved first time, it has been invalidated, how can you move it again?

  1. 在定义foo (T && Z )(TZ可以是任何东西)时,在定义为何体内我应该使用std::move(Z),因为Z已经由右值引用传递了,何时应该我使用std::move吗?
  1. When defining foo (T && Z )(T, Z can be anything), in the body of the definition Why on earth I should use std::move(Z) since Z is already passed by an rvalue reference and when should I use std::move?

推荐答案

您必须了解std::move不会移动任何内容,而是将其参数标记"为右值引用.从技术上讲,它将类型转换为右值引用.然后,右值引用将由相应的move构造函数或move赋值运算符移动.对于仅包含具有琐碎的移动ctor/赋值运算符的成员的对象,移动ctor/赋值运算符是琐碎的并且只是复制.通常,对象的移动ctor/赋值运算符会调用其所有成员的移动ctor/赋值运算符.

You have to understand that std::move does not move anything, but "marks" its argument to be a rvalue reference. Technically, it converts the type to a rvalue reference. Then, the rvalue reference it's being moved by the corresponding move constructor or move assignment operator. For objects that contain only members with trivial move ctors/assignment operators, the move ctor/assignment operator is trivial and simply copies. In general, the move ctor/assignment operator of the object calls the move ctor/assignment operator of all its members.

所以,只要你写


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

在分配y = std::move(x)右侧的

,您有一个类型为int&&的右值引用.但是,int没有简单的移动ctor,并且将右值简单地复制到y中,在x中没有任何更改.

on the right hand side of the assignment y = std::move(x), you have a rvalue reference of type int&&. However, int does not have a non-trivial move ctor, and the rvalue is simply copied into y, nothing is changed in 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的move构造函数启动,并窃取"(即交换内部指针等)s的资源,因为后者是右值引用.最后,s将不包含任何元素.

is different. The move constructor of moved_s kicks in, and "steals" (i.e. swaps internal pointers etc) the resource of s, because the latter is a rvalue reference. At the end, s will not contain any element.

这篇关于移动构造函数和std :: move混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆