1。 “这是什么?”
虽然std::move() 在技术上是一个函数 - 我会说它真的是一个函数。它是编译器考虑表达式值的方式之间的一种转换器。
2。 “它有什么作用?”
首先要注意的是std::move() 实际上并没有移动任何东西。它将表达式从lvalue(例如命名变量)更改为xvalue。一个 xvalue 告诉编译器:
你可以掠夺我,移动我持有的任何东西并在其他地方使用(因为反正我很快就会被摧毁)”。
换句话说,当您使用std::move(x) 时,您允许编译器蚕食x。因此,如果x 在内存中有自己的缓冲区 - 在std::move() 之后,编译器可以让另一个对象拥有它。
您也可以从prvalue 移动(例如您正在传递的临时地址),但这很少有用。
3。 “什么时候应该使用?”
问这个问题的另一种方式是“我会为了什么而蚕食现有对象的资源?”好吧,如果您正在编写应用程序代码,那么您可能不会对编译器创建的临时对象进行过多处理。所以主要你会在构造函数、操作符方法、标准库算法等函数等地方执行此操作。在这些地方,对象会自动创建和销毁很多。当然,这只是经验法则。
典型的用途是将资源从一个对象“移动”到另一个对象,而不是复制。 @Guillaume 链接到 this page,其中有一个简单的简短示例:用更少的复制交换两个对象。
template <class T>
swap(T& a, T& b) {
T tmp(a); // we now have two copies of a
a = b; // we now have two copies of b (+ discarded a copy of a)
b = tmp; // we now have two copies of tmp (+ discarded a copy of b)
}
使用 move 可以交换资源而不是复制它们:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
想想当T 是大小为n 的vector<int> 时会发生什么。在第一个版本中,您读取和写入 3*n 个元素,在第二个版本中,您基本上只读取和写入指向向量缓冲区的 3 个指针,以及 3 个缓冲区的大小。当然T的班级需要知道怎么搬家;你的班级应该有一个移动赋值运算符和一个 T 班级的移动构造函数才能工作。