技术在于交流、沟通,本文为博主原创文章转载请注明出处并保持作品的完整性
这次主要介绍一下迭代器适配器.以reverse_iterator(反向迭代器),insert_iterator(插入迭代器),ostream_iterator(输出迭代器)迭代器和算法中的copy函数做参考
迭代器适配器主要运用包含及操作符重载实现(主要操作符重载有operator*,operator=,operator++,operator--)
其实本节主要就是介绍运算符重载
1.reverse_iterator反向迭代器的实现
下面是reverse_iterator的源码
templateclass reverse_iterator : public iterator ::iterator_category, typename iterator_traits<_Iterator>::value_type, typename iterator_traits<_Iterator>::difference_type, typename iterator_traits<_Iterator>::pointer, typename iterator_traits<_Iterator>::reference> { protected: _Iterator current; typedef iterator_traits<_Iterator> __traits_type; public: typedef _Iterator iterator_type; typedef typename __traits_type::difference_type difference_type; typedef typename __traits_type::pointer pointer; typedef typename __traits_type::reference reference; /** * The default constructor value-initializes member @p current. * If it is a pointer, that means it is zero-initialized. */ // _GLIBCXX_RESOLVE_LIB_DEFECTS // 235 No specification of default ctor for reverse_iterator reverse_iterator() : current() { } /** * This %iterator will move in the opposite direction that @p x does. */ explicit reverse_iterator(iterator_type __x) : current(__x) { } /** * The copy constructor is normal. */ reverse_iterator(const reverse_iterator& __x) : current(__x.current) { } /** * A %reverse_iterator across other types can be copied if the * underlying %iterator can be converted to the type of @c current. */ template reverse_iterator(const reverse_iterator<_Iter>& __x) : current(__x.base()) { } /** * @return @c current, the %iterator used for underlying work. */ iterator_type base() const { return current; } /** * @return A reference to the value at @c --current * * This requires that @c --current is dereferenceable. * * @warning This implementation requires that for an iterator of the * underlying iterator type, @c x, a reference obtained by * @c *x remains valid after @c x has been modified or * destroyed. This is a bug: http://gcc.gnu.org/PR51823 */ reference operator*() const { _Iterator __tmp = current; return *--__tmp; } /** * @return A pointer to the value at @c --current * * This requires that @c --current is dereferenceable. */ pointer operator->() const { return &(operator*()); } /** * @return @c *this * * Decrements the underlying iterator. */ reverse_iterator& operator++() { --current; return *this; } /** * @return The original value of @c *this * * Decrements the underlying iterator. */ reverse_iterator operator++(int) { reverse_iterator __tmp = *this; --current; return __tmp; } /** * @return @c *this * * Increments the underlying iterator. */ reverse_iterator& operator--() { ++current; return *this; } /** * @return A reverse_iterator with the previous value of @c *this * * Increments the underlying iterator. */ reverse_iterator operator--(int) { reverse_iterator __tmp = *this; ++current; return __tmp; } /** * @return A reverse_iterator that refers to @c current - @a __n * * The underlying iterator must be a Random Access Iterator. */ reverse_iterator operator+(difference_type __n) const { return reverse_iterator(current - __n); } /** * @return *this * * Moves the underlying iterator backwards @a __n steps. * The underlying iterator must be a Random Access Iterator. */ reverse_iterator& operator+=(difference_type __n) { current -= __n; return *this; } /** * @return A reverse_iterator that refers to @c current - @a __n * * The underlying iterator must be a Random Access Iterator. */ reverse_iterator operator-(difference_type __n) const { return reverse_iterator(current + __n); } /** * @return *this * * Moves the underlying iterator forwards @a __n steps. * The underlying iterator must be a Random Access Iterator. */ reverse_iterator& operator-=(difference_type __n) { current += __n; return *this; } /** * @return The value at @c current - @a __n - 1 * * The underlying iterator must be a Random Access Iterator. */ reference operator[](difference_type __n) const { return *(*this + __n); } };
我们主要以几个比较明显的表示其适配器特征的函数为例
templateclass reverse_iterator : public iterator ::iterator_category, typename iterator_traits<_Iterator>::value_type, typename iterator_traits<_Iterator>::difference_type, typename iterator_traits<_Iterator>::pointer, typename iterator_traits<_Iterator>::reference> { protected: _Iterator current;//对应的正向迭代器 typedef iterator_traits<_Iterator> __traits_type;//迭代器萃取机 public: typedef _Iterator iterator_type;//逆向迭代器的5中associated types 和其他迭代器相同 typedef typename __traits_type::difference_type difference_type; typedef typename __traits_type::pointer pointer; typedef typename __traits_type::reference reference; //构造函数 reverse_iterator() : current() { } explicit reverse_iterator(iterator_type __x) : current(__x) { } reverse_iterator(const reverse_iterator& __x) : current(__x.current) { } //取出对应的正向迭代器 iterator_type base() const { return current; } //关键点在这里, *操作取值,取对应正向迭代器的上一位 reference operator*() const { _Iterator __tmp = current; return *--__tmp; } pointer operator->() const { return &(operator*()); } //前进变后退 后退变前进 reverse_iterator& operator++() { --current; return *this; } reverse_iterator operator++(int) { reverse_iterator __tmp = *this; --current; return __tmp; } reverse_iterator& operator--() { ++current; return *this; } reverse_iterator operator--(int) { reverse_iterator __tmp = *this; ++current; return __tmp; } reverse_iterator operator+(difference_type __n) const { return reverse_iterator(current - __n); } reverse_iterator& operator+=(difference_type __n) { current -= __n; return *this; } reverse_iterator operator-(difference_type __n) const { return reverse_iterator(current + __n); } reverse_iterator& operator-=(difference_type __n) { current += __n; return *this; } reference operator[](difference_type __n) const { return *(*this + __n); } };
下面是反向迭代器的起点和终点函数及图解
reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); }
总结 反向迭代器,它包含其正向迭代器,使用重载其原来的operator*,operator++等操作实现其反向功能
2.insert_iterator
首先看一下算法中的copy函数源码(G2.9)
template<class InputIterator, class OutputIterator> OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) { while (first!=last) { *result = * first; ++result; ++first; } }
注意copy()函数中没有申请新的内存,采取的方式是直接赋值,那么当内存不够使用时,调用copy函数会报错
namespace wzj009 { void test_Insert_Iterator() { int myArray[] = {10,20,30,40,50,60,70}; vector<int> v1; v1.resize(6);//申请内存为6 copy(myArray, myArray + 7, v1.begin());//copy7个元素过来导致越界 for(auto i : v1) { cout << i << endl; } } }
现在我们看下面这段代码是够能够编译通过
namespace wzj010 { void test_Insert_Iterator() { int myArray[] = {10,20,30,40,50,60,70}; vector<int> v1; v1.resize(0); copy(myArray, myArray + 7, inserter(v1,v1.begin())); for(auto i : v1) { cout << i << endl; } } }
我们从copy的源码中可以看得出,它的每一个方法都是写死的,那么为什么这几就能编译通过,这份功劳应该归功于运算符重载,因为insert方法会调用到insert_iterator,而insert_iterator重载了operator=,进而实现了该功能
我们看一下insert_iterator的源码
templateclass insert_iterator : public iterator void, void, void, void> { protected: _Container* container; typename _Container::iterator iter; public: typedef _Container container_type; insert_iterator(_Container& __x, typename _Container::iterator __i) : container(&__x), iter(__i) {} … insert_iterator& operator=(const typename _Container::value_type& __value) { iter = container->insert(iter, __value); ++iter; return *this; } insert_iterator& operator=(typename _Container::value_type&& __value)//关键点在这里,它重载了operator= 使copy函数中的 *result = * first; 调用这里的operator函数 { iter = container->insert(iter, std::move(__value)); ++iter; return *this; } … }
templateinline insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) { return insert_iterator<_Container>(__x, typename _Container::iterator(__i)); }//这个函数使insert调用insert_iterator
虽然运算符重载有时使我们很难读懂代码,但其功能是非常强大的
3 ostream_iterator
看下面代码
namespace wzj011 { void test_ostream_iterator() { vector<int> v; for(int i = 0;i<10; i++) v.push_back(i*10); std::ostream_iterator<int> out_it(std::cout, "-");//将将std::cout绑定在out_it,并且输出每个元素时加以"-" copy(v.begin(),v.end(),out_it); } }
我紧紧是将v copy给 out_it 却输出了out_it内的元素, 那么此时我的copy功能实现了其std::cout,那么copy函数这个功能任然要归功于函数重载
templatechar, typename _Traits = char_traits<_CharT> > class ostream_iterator : public iterator void, void, void, void> { … private: ostream_type* _M_stream; const _CharT* _M_string; public: /// Construct from an ostream. ostream_iterator(ostream_type& __s) : _M_stream(&__s), _M_string(0) {}//std::ostream_iterator out_it(std::cout, “-“)将_M_stream 绑定为std::cout “-“赋值给_M_string ostream_iterator(ostream_type& __s, const _CharT* __c) : _M_stream(&__s), _M_string(__c) { } /// Copy constructor. ostream_iterator(const ostream_iterator& __obj) : _M_stream(__obj._M_stream), _M_string(__obj._M_string) { } /// Writes @a value to underlying ostream using operator<<. If /// constructed with delimiter string, writes delimiter to ostream. ostream_iterator& operator=(const _Tp& __value)// { __glibcxx_requires_cond(_M_stream != 0, _M_message(__gnu_debug::__msg_output_ostream) ._M_iterator(*this)); *_M_stream << __value;//将value传递给_M_stream 使其作出输出动作 if (_M_string) *_M_stream << _M_string; return *this; } … };
以上的三种迭代器适配器都非常好理解,更重要的是在于我们要理解他的设计理念,运算重载功能非常强大,要好好利用
参考侯捷<