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>::d ifference_type Difference_type; typedef Iterator Pointer; typedef value_type&& Reference; Move_iterator () {} explicit Move_iterator (iterator it): current (IT) {} template<typename iter> Move_itera Tor (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 (Curren T[n]); } };
From the realization can be seen, the basic is the ordinary iterator added outer packaging.
Some of the points that are particularly noteworthy are:
typedef value_type&&operatorconst -Decltype (Std::move (Current[n])) { return operator* ()const{return std::move (*current);}
It can be found that this iterator renders the difference by casting an rvalue reference at the time of the dereference, so that all elements "removed" from a container can be implemented
#include <vector>#include<algorithm>#include<stack>#include<iostream>#include<string>using namespacestd;intMain () {std::vector<STD::string> foo (3); Std::vector<STD::string> bar{" One"," Both","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;}
For this program, you can track the last bar after the copy, although still contains three elements, but all become "", visible has been "hollowed out"
The back clear just makes bar size reduced to 0, which is superfluous.
All the difference, but because we input parameters with move_iterator wrapped a layer:std::move_iterator<iter>(Bar.begin ())
There is Move_iterator is a template class, not a template function, so you need to explicitly write out the template parameters, here is a bit verbose.
You can also look at another example of a solution reference
#include <iterator>#include<string>#include<iostream>#include<vector>using namespacestd;intMain () {std::stringStr[] = {" One"," Both","three"}; Std::vector<STD::string>foo; Std::move_iterator<STD::string*>it (str); for(inti =0; I <3; i++) {Foo.push_back (*it); ++it; } std::cout<<"foo:"; for(std::string& X:foo) Std::cout <<" "<<x; Std::cout<<"\ n"; return 0;}
Because normal pointers can also be recognized as iterators by Iterator_traits, they can also be packaged with Move_iterator
C++11 Move_iterator