Wikipedia 页面上的 C ++ 11 R 值引用和移动构造函数
Type &&
),那么将使用 move 构造函数而不是 copy 构造函数。std::move()
是一种强制类型转换,它生成对对象的右值引用,从而能够从该对象进行移动。这是避免复制的新 C ++ 方法。例如,使用 move 构造函数, std::vector
可以将其内部指针复制到数据中,并将其复制到新对象中,而使移动后的对象处于从状态移出的状态,因此不复制所有数据。这将是 C ++ 有效的。
尝试谷歌搜索以获取移动语义,右值,完美转发。
虽然std::move()
从技术上讲是一个函数 - 我会说它并不是一个真正的函数。它在编译器考虑表达式值的方式之间是一种转换器。
首先要注意的是std::move()
实际上并没有移动任何东西。它将表达式从左值(例如命名变量)更改为xvalue 。一个 xvalue 告诉编译器:
您可以掠夺我,将我持有的任何物品转移到其他地方使用(因为无论如何我都会很快被销毁)”。
换句话说,当您使用std::move(x)
,您将允许编译器吞并x
。因此,如果x
在内存中拥有自己的缓冲区,则在std::move()
,编译器可以拥有另一个对象。
您也可以从prvalue (例如您要经过的临时地址)移开,但这很少有用。
提出此问题的另一种方式是 “我将蚕食现有对象的资源用于什么?” 好吧,如果您正在编写应用程序代码,则可能不会把编译器创建的临时对象弄得一团糟。因此,主要是在诸如构造函数,运算符方法,标准库算法之类的函数等位置执行此操作,在这些位置会大量自动创建和销毁对象。当然,这只是一个经验法则。
一种典型的用法是将资源从一个对象 “移动” 到另一个对象,而不是复制。 @Guillaume 链接到此页面,该页面有一个简单的简短示例:交换两个对象且复制较少。
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
配备一个移动分配运算符和一个移动构造函数,以使其正常工作。
当需要将对象的内容 “转移” 到其他地方而不进行复制时,可以使用 move 方式(即,内容不重复,这就是为什么可以将其用于某些不可复制的对象(例如 unique_ptr)的原因)。一个对象也可以使用 std :: move 来获取临时对象的内容而无需执行复制操作(并节省大量时间)。
这个链接确实帮助了我:
http://thbecker.net/articles/rvalue_references/section_01.html
很抱歉,我的答案来不及了,但是我也正在为 std :: move 寻找一个好的链接,我发现上面的链接有点 “严肃”。
这将重点放在 r 值引用上,在这种情况下您应该使用它们,而且我认为它更详细,这就是为什么我想在这里共享此链接。