...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Note | |
---|---|
The first 3 chapters are the adapted from the article A Brief Introduction to Rvalue References by Howard E. Hinnant, Bjarne Stroustrup, and Bronek Kozicki |
Copying can be expensive. For example, for vectors v2=v1
typically
involves a function call, a memory allocation, and a loop. This is of course
acceptable where we actually need two copies of a vector, but in many cases,
we don't: We often copy a vector
from one place to another, just to proceed to overwrite the old copy. Consider:
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) }
But, we didn't want to have any copies of a or b, we just wanted to swap them. Let's try again:
template <class T> void swap(T& a, T& b) { T tmp(::boost::move(a)); a = ::boost::move(b); b = ::boost::move(tmp); }
This move()
gives its target the value of its argument, but is not obliged to preserve
the value of its source. So, for a vector
,
move()
could reasonably be expected to leave its argument as a zero-capacity vector
to avoid having to copy all the elements. In other words, move
is a potentially destructive copy.
In this particular case, we could have optimized swap by a specialization. However, we can't specialize every function that copies a large object just before it deletes or overwrites it. That would be unmanageable.
In C++0x, move semantics are implemented with the introduction of rvalue references.
They allow us to implement move()
without verbosity or runtime overhead. Boost.Move is a library that offers tools to implement
those move semantics not only in compilers with rvalue
references
but also in compilers
conforming to C++03.