更多精彩内容,请关注微信公众号:后端技术小屋后端
iterator iterator.h stl_iterator.h stl_iterator_base.h
在STL中,迭代器分为输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器。这里先讲输入迭代器这个大类。数组
input_iterator
iterator_category
类型为input_iterator_tag
)。在每种迭代器类型中,必须定义iterator_category
表示迭代器种类,value_type
表示迭代器指向的实例类型,difference_type
表示迭代器距离的类型,pointer
表示迭代器指向的实例的指针类型,reference
表示实例应用类型。template <class _Tp, class _Distance> struct input_iterator { typedef input_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; };
ouput_iterator
iterator_category
类型为output_iterator_tag
)struct output_iterator { typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; };
forward_iterator
iterator_category
类型为forward_iterator_tag
,然后者正是input_iterator_tag
的派生类)template <class _Tp, class _Distance> struct forward_iterator { typedef forward_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; struct forward_iterator_tag : public input_iterator_tag {};
bidirectional_iterator
iterator_category
类型为bidirectional_iterator_tag
,然后者正是forward_iterator_tag
的派生类。template <class _Tp, class _Distance> struct bidirectional_iterator { typedef bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; struct bidirectional_iterator_tag : public forward_iterator_tag {};
random_access_iterator
n
。注意iterator_category
类型为random_access_iterator_tag
,然后者正是bidirectional_iterator_tag
的派生类。template <class _Tp, class _Distance> struct random_access_iterator { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; };
做用:将不一样种类迭代器中定义的iterator_category
, value_type
, difference_type
, pointer
, reference
类型转化为萃取器自身的类型。当上层调用萃取器iterator_traits
时,迭代器类型(做为iterator_traits
的模板参数)对上层是透明的。微信
实现以下,因为2.1
中全部迭代器中,都定义了iterator_category
等类型,iterator_traits
即可将迭代器中的类型导出做为自身类型。dom
template <class _Iterator> struct iterator_traits { typedef typename _Iterator::iterator_category iterator_category; typedef typename _Iterator::value_type value_type; typedef typename _Iterator::difference_type difference_type; typedef typename _Iterator::pointer pointer; typedef typename _Iterator::reference reference; };
某些特殊状况下,原始指针_Tp*
也可做为iterator使用(例如数组中的原始指针)。由于_Tp*
内部并未定义以上类型,所以iterator_traits
须要对_Tp*
和const _Tp*
进行特化。函数
template <class _Tp> struct iterator_traits<_Tp*> { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; template <class _Tp> struct iterator_traits<const _Tp*> { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; typedef const _Tp* pointer; typedef const _Tp& reference; };
有了iterator_traits
,迭代器操做即可根据不一样的类型进行不一样的实现。源码分析
实现以下,模板入参为迭代器,iterator_category
函数所返回的是迭代器中iterator_category
类型的实例。this
template <class _Iter> inline typename iterator_traits<_Iter>::iterator_category iterator_category(const _Iter& __i) { return __iterator_category(__i); } template <class _Iter> inline typename iterator_traits<_Iter>::iterator_category __iterator_category(const _Iter&) { typedef typename iterator_traits<_Iter>::iterator_category _Category; return _Category(); }
实现以下,首先经过iterator_category
函数获取迭代器种类,再将其值做为参数传给__distance
函数。指针
template <class _InputIterator, class _Distance> inline void distance(_InputIterator __first, _InputIterator __last, _Distance& __n) { __STL_REQUIRES(_InputIterator, _InputIterator); __distance(__first, __last, __n, iterator_category(__first)); }
返回结果关键在于__distance
函数。对于不一样的迭代器类型,重载了不一样的__distance
实现,这些实现使用了迭代器中的iterator_category
类型进行区分。code
例如:对于随机访问迭代器类型,计算distance
只需将两个迭代器相减便可。对象
template <class _RandomAccessIterator, class _Distance> inline void __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance& __n, random_access_iterator_tag) { __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); __n += __last - __first; }
对于其余迭代器(都属于input_iterator
类型),实现上则须要从__first
步步递进并计数,直到到达__last
为止,最后返回计数值
template <class _InputIterator, class _Distance> inline void __distance(_InputIterator __first, _InputIterator __last, _Distance& __n, input_iterator_tag) { while (__first != __last) { ++__first; ++__n; } }
对于advance函数, 不一样类型迭代器其实现也不尽相同。
input_iterator
: 输入迭代器只能支持前向自增1。n必须大于等于零,此时迭代器执行n次自增1。template <class _InputIterator, class _Distance> inline void advance(_InputIterator& __i, _Distance __n) { __STL_REQUIRES(_InputIterator, _InputIterator); __advance(__i, __n, iterator_category(__i)); } template <class _RandomAccessIterator, class _Distance> inline void __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) { __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); __i += __n; } template <class _BidirectionalIterator, class _Distance> inline void __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIterator, _BidirectionalIterator); if (__n >= 0) while (__n--) ++__i; else while (__n++) --__i; } template <class _InputIter, class _Distance> inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { while (__n--) ++__i; }
反向迭代器通常用于逆向遍历容器。其自增和自减的方向与其封装的迭代器正好是反过来的。
iterator_type base() const { return current; } reference operator*() const { _Iterator __tmp = current; return *--__tmp; } _Self& operator++() { --current; return *this; } _Self operator++(int) { _Self __tmp = *this; --current; return __tmp; } _Self& operator--() { ++current; return *this; } _Self operator--(int) { _Self __tmp = *this; ++current; return __tmp; }
构造时,输入类型为_Iterator
的迭代器对象__x
, reverse_iterator<_Iterator>
即为_Iterator
的逆操做。API以下:
base
: 返回被封装的__x
迭代器operator*
: 返回*(__x-1)
(容器的end iterator为虚边界,当基于end iterator生成反向迭代器时,执行operator*应当返回容器的最后一个元素)operator++
: __x
自减1operator--
: __x
自增1back_inserter_iterator
, front_insert_iterator
, insert_iterator
中都定义了iterator_category
类型为output_iterator_tag
。所以它们都是输出迭代器。
举back_insert_iterator
为例,其中模板参数_Container
为STL容器类型,iterator_category
为output_iterator_tag
类型。
template <class _Container> class back_insert_iterator { protected: _Container* container; public: typedef _Container container_type; typedef output_iterator_tag iterator_category; ... };
用于向容器尾部插入元素
back_insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->push_back(__value); return *this; }
back_inserter_iterator
执行operator=
操做时,老是对容器push_back
(容器必须实现push_back接口)
用于向容器头部插入元素
explicit front_insert_iterator(_Container& __x) : container(&__x) {} front_insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->push_front(__value); return *this;
front_inserter_iterator
执行operator=
操做时,老是对容器push_front
(容器必须实现push_front接口)
用于向容器指定位置插入元素
insert_iterator(_Container& __x, typename _Container::iterator __i) : container(&__x), iter(__i) {} insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { iter = container->insert(iter, __value); ++iter; return *this; }
insert_iterator
构造时传入容器和迭代器iter
,执行operator=
操做时,老是对容器执行insert
, 插入位置由迭代器iter
决定(容器必须实现insert接口)
推荐阅读
更多精彩内容,请扫码关注微信公众号:后端技术小屋。若是以为文章对你有帮助的话,请多多分享、转发、在看。