Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Move iterators

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 an 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/move.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_ == 0; }
};

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;
}


PrevUpHomeNext