更多精彩內容,請關注微信公衆號:後端技術小屋後端
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接口)
推薦閱讀
更多精彩內容,請掃碼關注微信公衆號:後端技術小屋。若是以爲文章對你有幫助的話,請多多分享、轉發、在看。