![]() |
注意 |
---|---|
前三章改编自 Howard E. Hinnant、Bjarne Stroustrup 和 Bronek Kozicki 的文章 Rvalue 引用简述 |
复制操作可能代价很高。例如,对于 vector v2=v1
通常涉及函数调用、内存分配和循环。如果我们确实需要 vector 的两个副本,这当然是可以接受的,但在许多情况下,我们不需要这样做:我们经常将一个 vector
从一个地方复制到另一个地方,只是为了随后覆盖旧副本。考虑以下情况:
template <class T> void swap(T& a, T& b) { T tmp(a); // now we have two copies of a a = b; // now we have two copies of b b = tmp; // now we have two copies of tmp (aka a) }
但是,我们不希望有 a 或 b 的任何副本,我们只是想交换它们。让我们再试一次:
template <class T> void swap(T& a, T& b) { T tmp(::boost::move(a)); a = ::boost::move(b); b = ::boost::move(tmp); }
这个 move()
将其参数的值赋予其目标,但不一定保留其源的值。因此,对于 vector
,move()
可以合理地预期将其参数保留为零容量的 vector,以避免复制所有元素。换句话说,move 是一种潜在的破坏性复制。
在这种特定情况下,我们可以通过特化来优化 swap。但是,我们不能特化每个在删除或覆盖大型对象之前复制它的函数。那将是无法管理的。
在 C++0x 中,移动语义是通过引入右值引用来实现的。它们允许我们实现 move()
,而无需冗长或运行时开销。Boost.Move 是一个库,它提供了工具来实现这些移动语义,不仅在具有 rvalue references
的编译器中,而且在符合 C++03 标准的编译器中。