...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
template<class Iterator> class move_iterator; template<class It> move_iterator<It> make_move_iterator(const It &it);
move_iterator
is an iterator
adaptor with the same behavior as the underlying iterator except that its dereference
operator implicitly converts the value returned by the underlying iterator's
dereference operator to a rvalue reference: boost::move(*underlying_iterator)
It is a read-once iterator, but can have up to random access traversal characteristics.
move_iterator
is very useful
because some generic algorithms and container insertion functions can be called
with move iterators to replace copying with moving. For example:
//header file "movable.hpp" #include <boost/move/core.hpp> #include <boost/move/traits.hpp> //A movable class class movable { BOOST_MOVABLE_BUT_NOT_COPYABLE(movable) int value_; public: movable() : value_(1){} //Move constructor and assignment movable(BOOST_RV_REF(movable) m) { value_ = m.value_; m.value_ = 0; } movable & operator=(BOOST_RV_REF(movable) m) { value_ = m.value_; m.value_ = 0; return *this; } bool moved() const //Observer { return !value_; } int value() const //Observer { return value_; } }; namespace boost{ template<> struct has_nothrow_move<movable> { static const bool value = true; }; } //namespace boost{
movable
objects can be moved
from one container to another using move iterators and insertion and assignment
operations.w
#include <boost/container/vector.hpp> #include "movable.hpp" #include <cassert> int main() { using namespace ::boost::container; //Create a vector with 10 default constructed objects vector<movable> v(10); assert(!v[0].moved()); //Move construct all elements in v into v2 vector<movable> v2( boost::make_move_iterator(v.begin()) , boost::make_move_iterator(v.end())); assert(v[0].moved()); assert(!v2[0].moved()); //Now move assign all elements from in v2 back into v v.assign( boost::make_move_iterator(v2.begin()) , boost::make_move_iterator(v2.end())); assert(v2[0].moved()); assert(!v[0].moved()); return 0; }