template<typename Iterator> class move_iterator
{
Iterator current;
public:
typedef Iterator iterator_type;
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef Iterator pointer;
typedef value_type&& reference;
move_iterator(){}
explicit move_iterator(Iterator it):current(it){}
template<typename Iter> move_iterator(const move_iterator<Iter>& it):current(it.current){}
template<typename Iter> move_iterator& operator=(const move_iterator<Iter>&it)
{
current = it.current;
}
iterator_type base() const{ return current;}
pointer operator->()const{return current;}
reference operator*()const{return std::move(*current);}
move_iterator&operator++(){++current; return *this;}
move_iterator&operator--(){--current; return *this;}
move_iterator&operator++(int){move_iterator temp = *this; ++current; return temp;}
move_iterator&operator--(int){move_iterator temp = *this; --current; return temp;}
move_iterator operator+(difference_type n) const {return move_iterator(current + n);}
move_iterator operator-(difference_type n) const {return move_iterator(current - n);}
move_iterator operator+=(difference_type n) {current += n; return *this;}
move_iterator operator-=(difference_type n) {current -= n; return *this;}
auto operator[](difference_type n) const -> decltype(std::move(current[n]))
{
return std::move(current[n]);
}
};
从实现上可以看出,基本是普通Iterator加了外包装。
其中特别值得注意的几个点:
typedef value_type&& reference; auto operator[](difference_type n) const -> decltype(std::move(current[n])) { return std::move(current[n]); } reference operator*()const{return std::move(*current);}
可以发现,这种迭代器呈现出差别就在解引用的时候强制转换成右值引用,这样就可以实现从一个容器中”移走“所有的元素
#include<vector>
#include<algorithm>
#include<stack>
#include<iostream>
#include<string>
using namespace std;
int main()
{
std::vector<std::string> foo(3);
std::vector<std::string> bar{"one", "two", "three"};
typedef std::vector<std::string>::iterator Iter;
std::copy(std::move_iterator<Iter>(bar.begin()),
std::move_iterator<Iter>(bar.end()), foo.begin());
bar.clear();
std::cout << "foo:";
for(std::string& x : foo) cout << ' ' << x;
std::cout << '\n';
return 0;
}