STL原始碼分析 iterator

2022-07-12 06:00:14 字數 4641 閱讀 4005

iterator

iterator.h

stl_iterator.h

stl_iterator_base.h

在stl中,迭代器分為輸入迭代器、輸出迭代器、前向迭代器、雙向迭代器、隨機訪問迭代器。這裡先講輸入迭代器這個大類。

template struct input_iterator ;
struct output_iterator ;
template struct forward_iterator ;

struct forward_iterator_tag : public input_iterator_tag {};

template struct bidirectional_iterator ;

struct bidirectional_iterator_tag : public forward_iterator_tag {};

template struct random_access_iterator ;
作用:將不同種類迭代器中定義的iterator_category,value_type,difference_type,pointer,reference型別轉化為萃取器自身的型別。當上層呼叫萃取器iterator_traits時,迭代器型別(作為iterator_traits的模板引數)對上層是透明的。

實現如下,由於2.1中所有迭代器中,都定義了iterator_category等型別,iterator_traits便可將迭代器中的型別匯出作為自身型別。

template struct iterator_traits ;
某些特殊情況下,原始指標_tp*也可作為iterator使用(例如陣列中的原始指標)。因為_tp*內部並未定義以上型別,因此iterator_traits需要對_tp*const _tp*進行特化。

template struct iterator_traits<_tp*> ;

template struct iterator_traits;

有了iterator_traits,迭代器操作便可根據不同的型別進行不同的實現。

實現如下,模板入參為迭代器,iterator_category函式所返回的是迭代器中iterator_category型別的例項。

template inline typename iterator_traits<_iter>::iterator_category

iterator_category(const _iter& __i)

template inline typename iterator_traits<_iter>::iterator_category

__iterator_category(const _iter&)

實現如下,首先通過iterator_category函式獲取迭代器種類,再將其值作為引數傳給__distance函式。

template inline void distance(_inputiterator __first, 

_inputiterator __last, _distance& __n)

返回結果關鍵在於__distance函式。對於不同的迭代器型別,過載了不同的__distance實現,這些實現使用了迭代器中的iterator_category型別進行區分。

例如:對於隨機訪問迭代器型別,計算distance只需將兩個迭代器相減即可。

template inline void __distance(_randomaccessiterator __first, 

_randomaccessiterator __last,

_distance& __n, random_access_iterator_tag)

對於其他迭代器(都屬於input_iterator型別),實現上則需要從__first步步遞進並計數,直到到達__last為止,最後返回計數值

template inline void __distance(_inputiterator __first, _inputiterator __last,

_distance& __n, input_iterator_tag)

}

對於advance函式, 不同型別迭代器其實現也不盡相同。

template inline void advance(_inputiterator& __i, _distance __n) 

template inline void __advance(_randomaccessiterator& __i, _distance __n,

random_access_iterator_tag)

template inline void __advance(_bidirectionaliterator& __i, _distance __n,

bidirectional_iterator_tag)

template inline void __advance(_inputiter& __i, _distance __n, input_iterator_tag)

反向迭代器一般用於逆向遍歷容器。其自增和自減的方向與其封裝的迭代器正好是反過來的。

iterator_type base() const 

reference operator*() const

_self& operator++()

_self operator++(int)

_self& operator--()

_self operator--(int)

構造時,輸入型別為_iterator的迭代器物件__x,reverse_iterator<_iterator>即為_iterator的逆操作。api如下:

back_inserter_iterator,front_insert_iterator,insert_iterator中都定義了iterator_category型別為output_iterator_tag。因此它們都是輸出迭代器。

back_insert_iterator為例,其中模板引數_container為stl容器型別,iterator_categoryoutput_iterator_tag型別。

template class back_insert_iterator ;
用於向容器尾部插入元素

back_insert_iterator<_container>&

operator=(const typename _container::value_type& __value)

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)

insert_iterator<_container>&

operator=(const typename _container::value_type& __value)

insert_iterator構造時傳入容器和迭代器iter,執行operator=操作時,總是對容器執行insert, 插入位置由迭代器iter決定(容器必須實現insert介面)

推薦閱讀

STL原始碼分析set

include include using namespace std int main set iset ia,ia 5 cout size iset.size endl cout 3 count iset.count 3 endl iset.insert 3 cout size iset.siz...

STL原始碼分析 List

鍊錶是一種線性表,但不會按照線性的順序儲存。鍊錶每次插入和刪除乙個元素,只配置或者釋放乙個元素空間,對於任何位置的元素的插入或者刪除,list永遠是常量時間複雜度。template struct listnode 節點物件包含兩個節點物件指標,分別指向前乙個節點和後乙個節點,還有乙個節點物件存放的資...

STL原始碼分析 string

從定義可知,string其實是base string的特化類,string使用預設的記憶體分配器 stl default allocator chart template class alloc stl default allocator chart class basic string typed...