迭代器的基本概念
迭代器(iterator)模式又稱為游標(Cursor)模式,用于提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。或者這樣說可能更容易理解:Iterator模式是運用于聚合對象的一種模式,通過運用該模式,使得我們可以在不知道對象內部表示的情況下,按照一定順序(由iterator提供的方法)訪問聚合對象中的各個元素。
迭代器產生原因(或者本質)
Iterator 類的訪問方式就是把不同集合類的訪問邏輯抽象出來,使得不用暴露集合內部的結構而達到循環遍歷集合的效果。
迭代器的類型
輸入迭代器 ( InputIterator ) 、輸出迭代器 ( OutputIterator ) 、前向迭代器(ForwardIterator ) 、雙向迭代器 ( BidirectionalIterator ) 、隨機訪問迭代器(RandomAccessIterator ) 。
每個迭代器類型對應的操作。
類別 簡寫 | 輸出 output | 輸入 input | 前向 Forward | 雙向 Bidirection | 隨機 Random |
讀 | =* p | =*p | =*p | =*p | |
訪問 | -> | -> | -> | -> [] | |
寫 | * p = | *p= | *p= | *p= | |
迭代 | ++ | ++ | ++ | ++/-- | ++/--/+/-/+=/-= |
比較 | ==/!= | ==/!= | ==/!= | ==/!=/</>/<=/>= |
五種迭代器之間的關系圖
為什么定義這么多迭代器
物盡其用,使得具體的操作使用具體類型的迭代器,避免迭代器的功能太大或者太小,導致使用起來不方便。每個容器及其對應的迭代器的類型圖表如下:
容器 | 類內迭代器類別 |
vector | 隨機訪問迭代器 |
deque | 隨機訪問迭代器 |
list | 雙向迭代器 |
set | 雙向迭代器 |
multiset | 雙向迭代器 |
map | 雙向迭代器 |
multimap | 雙向迭代器 |
unordered_set | 前向迭代器 |
unordered_multiset | 前向迭代器 |
unordered_map | 前向迭代器 |
unordered_multimap | 前向迭代器 |
流迭代器
流迭代器是特殊的迭代器,可以將輸入 / 輸出流作為 容器 看待 ( 因為輸入輸出都有 緩沖 區 的概念 ) 。因此,任何接受迭代器參數的算法都可以和流一起工作。關于流迭代器的模板形式:
#include <iterator>
template< class T,class CharT = char,class Traits = std::char_traits<CharT>,class Distance = std::ptrdiff_t> class istream_iterator
: public std::iterator<std::input_iterator_tag, T, Distance, const T*, const T&>;template< class T,class CharT = char,class Traits = std::char_traits<CharT>,class Distance = std::ptrdiff_t> class istream_iterator;template< class T,class CharT = char,class Traits = std::char_traits<CharT>> class ostream_iterator
: public std::iterator<std::output_iterator_tag, void, void, void, void>;template< class T,class CharT = char,class Traits = std::char_traits<CharT>> class ostream_iterator;
以及兩種流迭代器的構造函數
//輸出流迭代器的構造函數
ostream_iterator(ostream_type& stream, const CharT* delim);
ostream_iterator(ostream_type& stream);//輸入流迭代器的構造函數
constexpr istream_iterator();
istream_iterator( istream_type& stream );
istream_iterator( const istream_iterator& other ) = default;
輸入輸出流迭代器的使用示例:
void test()
{vector<int> numbers{1, 2, 3, 4, 5};ostream_iterator<int> osi(cout, "\n");copy(numbers.begin(), numbers.end(), osi);
}void test()
{vector<int> numbers;istream_iterator<int> isi(cin);//對于vector插入元素應該調用push_back//copy(isi, istream_iterator<int>(), numbers.begin());//這樣寫會有bug,可以思考一下什么原因copy(isi, istream_iterator<int>(), std::back_inserter(numbers));copy(numbers.begin(), numbers.end(), ostream_iterator<int>(cout, "\n"));
}
迭代器適配器
back _ inserter 是函數模板,該函數模板的返回類型是類模板 back _ insert _ iterator ,而類模板back? _ i nsert _ iterator 底層調用了 push _ back 函數;
front _ inserter 是函數模板,該函數模板的返回類型是類模板 front _? insert _? iterator ,而類模板fron t? _ insert? _? iterator 底層調用了 push _ front 函數;
inserter 是函數模板,函數模板的返回類型是類模板 insert _ iterator ,而類模板insert_ iterator 底層調用了 insert 函數。
下面是三個函數模板的接口原型:
template< class Container >
std::back_insert_iterator<Container> back_inserter( Container& c );template< class Container >
std::front_insert_iterator<Container> front_inserter( Container& c );template< class Container >
std::insert_iterator<Container>
inserter( Container& c, typename Container::iterator i );
三者對應的可能實現如下:
template< class Container >
std::back_insert_iterator<Container> back_inserter( Container& c )
{return std::back_insert_iterator<Container>(c);
}template< class Container >
std::front_insert_iterator<Container> front_inserter( Container& c )
{return std::front_insert_iterator<Container>(c);
}template< class Container >
std::insert_iterator<Container>
inserter( Container& c, typename Container::iterator i )
{return std::insert_iterator<Container>(c, i);
}