文章目录
适配器是标准库中的一个通用概念。容器、迭代器和函数都有适配器(C++11出现了lambda函数、function类模板、bind函数,几乎取代了函数适配器)。本质上,适配器是一种机制,能使某种事物的行为看起来像另外一种一样。栈、队列、优先队列都属于容器适配器。本文主要介绍迭代器适配器。
迭代器适配器主要有三类:反向迭代器,插入迭代器,iostream迭代器。
插入迭代器
插入迭代器有三种类型,差异在于元素插入的位置:
back_inserter( Container& c )
,在容器尾部插入,只能对有push_back()的容器使用inserter( Container& c, Container::iterator i )
,在容器内部指定迭代器前插入,只能对有insert()的容器使用。front_inserter( Container& c )
,在容器头部插入,只能对有push_front()的容器使用。
假如你不能确定容器的大小,使用这三种迭代器,可以保证了不会造成越界的情况。
vector<int> v{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
fill_n(inserter(v, v.begin() + 1), 3, -2); // v:1 -2 -2 -2 2 3 4 5 6 7 8 9 10
vector<int> v2;
copy(v.begin(),v.end(),back_inserter(v2)); // v2:1 -2 -2 -2 2 3 4 5 6 7 8 9 10
deque<int> d;
copy(v.begin(),v.end(),front_inserter(d)); //逆序插入 d:10 9 8 7 6 5 4 3 2 -2 -2 -2 1
原理分析
每一个insert iterators 内部都维护有一个容器(必须由用户指定);容器当然有自己的迭代器,于是,当客户端对insert iterators做赋值(assign)操作时,就在insert iterators中被转为对该容器的选代器做插入操作,也就是说,在insert iterators的operator=操作符中调用底层容器的push_front()或push_back()或insert()操作函数。至于其它的迭代器惯常行为如operator++
,operator++(int)
,operator*
都被关闭功能,更没有提供operator--(int)
或operator--
或operator->
等功能。换句话说,insert iterators的前进、后退、取值、成员取用等操作都是没有意义的,甚至是不允许的。
下面是back_inserter源码:
template <class Container>
class back_insert_iterator
{
protected:
Container* container;
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit back_insert_iterator(Container& x) : container(&x) {
}
// 只有提供了push_back()操作的容器才能使用back_insert_iterator
back_insert_iterator<Container>&
operator=(const typename Container::value_type& value)
{
container->push_back(value);
return *this;
}
back_insert_iterator<Container>& operator*() {
return *this; }
back_insert_iterator<C