一、概述
迭代器是c++中一种检查容器内元素并遍历元素的数据类型。
迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。
迭代器(Iterator)是指针(pointer)的泛化,它允许程序员用相同的方式处理不同的数据结构(容器)。
每个容器定义了一种名为iterator的类型,这种类型支持迭代器的各种行为。
迭代器模式是23种设计模式之一,迭代器模式提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示,使得我们可以在不知道对象内部表示的情况下,按照一定顺序访问聚合对象中的各个元素。
二、STL中迭代器的类型
Input Iterator
:只能单步向前迭代元素,不允许修改由该类迭代器引用的元素。
Output Iterator
:该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。
Forward Iterator
:该类迭代器可以在一个正确的区间中进行读写操作,它拥有Input Iterator的所有特性,和Output Iterator的部分特性,以及单步向前迭代元素的能力。
Bidirectional Iterator
:该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。
Random Access Iterator
:该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。
这五类迭代器的从属关系,如下图所示,其中箭头A→B表示,A是B的强化类型,这也说明了如果一个算法要求B,那么A也可以应用于其中。
input
output
\ /
forward
|
bidirectional
|
random access
三、STL中迭代器的操作
对应上述迭代器类型,归纳总结不同迭代器的操作:
四、STL容器支持的迭代器类型
五、常用的迭代器函数
正向迭代器begin()从头结点开始,end()指向末尾节点+1,反向迭代器方向相反。
六、迭代器失效
容器的插入insert和erase操作可能导致迭代器失效,对于erase操作不要使用操作之前的迭代器,因为erase的那个迭代器一定失效了,正确的做法是返回删除操作时候的那个迭代器。
七、迭代器的辅助函数
STL 中有用于操作迭代器的三个函数模板,它们是:
- advance(p, n):使迭代器 p 向前或向后移动 n 个元素。
- distance(p, q):计算两个迭代器之间的距离,即迭代器 p 经过多少次 + + 操作后和迭代器 q 相等。如果调用时 p 已经指向 q 的后面,则这个函数会陷入死循环。
- iter_swap(p, q):用于交换两个迭代器 p、q 指向的值。
要使用上述模板,需要包含头文件 algorithm。下面的程序演示了这三个函数模板的 用法。
#include
#include
#include //要使用操作迭代器的函数模板,需要包含此文件
using namespace std;
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
list lst(a, a+5);
list ::iterator p = lst.begin();
advance(p, 2); //p向后移动两个元素,指向3
cout << "1)" << *p << endl; //输出 1)3
advance(p, -1); //p向前移动一个元素,指向2
cout << "2)" << *p << endl; //输出 2)2
list::iterator q = lst.end();
q--; //q 指向 5
cout << "3)" << distance(p, q) << endl; //输出 3)3
iter_swap(p, q); //交换 2 和 5
cout << "4)";
for (p = lst.begin(); p != lst.end(); ++p)
cout << *p << " ";
return 0;
}
程序的输出结果是:
1) 3
2) 2
3) 3
4) 1 5 3 4 2
八、迭代器中的traits
让我们来看下面的一段代码:
int ai[] = {3, 6, 9, 12, 15};
int *p = ai;
advance(p, 3);
cout <<"*p="<< *p << endl; //we get *p=12
可以看出advance不仅能够对像vector,list这样的容器处理,也可以对传统的数据指针作处理。而我们知道传统的int这种类型,是没有iterator_category的,因此如果我们使用想当然版本的_Iter_cat(p),它会执行typename int::iterator_category _Cat,毫无疑问这句话会失败,因为压根int就不是一个类类型,何谈取它的iterator_category呢。我们标准库设计的人员创造性的提出了标准版本的_Iter_cat(p),它绕了远路,但是将类型tag析取的过程转交给了iterator_traits类,由它通过iterator_traits<_Iter>::iterator_category 来获取_Iter的类型。现在我们有了iterator_traits类的辅助,我们就可以针对int这种特别的类型设计它的特化版本,也就是说我们的iterator_traits类对常见的迭代器类,直接使用迭代器类的iterator_category,而对于非迭代器类int这种,设计了特化版本的实现来返回它的迭代器tag。 根据我们的经验,int p这种指针类型支持随机存储,也就是说p+3,p+10都是可以的,因此我们针对普通指针的特化版本如下:
template //_Ty can be int, double...
struct iterator_traits<_Ty *>
{ // get traits from pointer
typedef random_access_iterator_tag iterator_category;
typedef _Ty value_type;
typedef ptrdiff_t difference_type;
typedef ptrdiff_t distance_type; // retained
typedef _Ty *pointer;
typedef _Ty& reference;
};
STL中”萃取机“的源码
iterator_traits
// 用于traits出迭代其所指对象的型别
template
struct iterator_traits
{
// 迭代器类型, STL提供五种迭代器
typedef typename Iterator::iterator_category iterator_category;
// 迭代器所指对象的型别
// 如果想与STL算法兼容, 那么在类内需要提供value_type定义
typedef typename Iterator::value_type value_type;
// 这个是用于处理两个迭代器间距离的类型
typedef typename Iterator::difference_type difference_type;
// 直接指向对象的原生指针类型
typedef typename Iterator::pointer pointer;
// 这个是对象的引用类型
typedef typename Iterator::reference reference;
};
// 针对指针提供特化版本
template
struct iterator_traits
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
};
// 针对指向常对象的指针提供特化
template
struct iterator_traits
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T* pointer;
typedef const T& reference;
};
type_traits
/**
* 用来标识真/假对象,利用type_traits响应结果来进行参数推导,
* 而编译器只有面对class object形式的参数才会做参数推导,
* 这两个空白class不会带来额外负担
*/
struct __true_type{};
struct __false_type{};
/**
* type_traits结构体设计
*/
template
struct __type_traits
{
// 不要移除这个成员
// 它通知能自动特化__type_traits的编译器, 现在这个__type_traits template是特化的
// 这是为了确保万一编译器使用了__type_traits而与此处无任何关联的模板时
// 一切也能顺利运作
typedef __true_type this_dummy_member_must_be_first;
// 以下条款应当被遵守, 因为编译器有可能自动生成类型的特化版本
// - 你可以重新安排的成员次序
// - 你可以移除你想移除的成员
// - 一定不可以修改下列成员名称, 却没有修改编译器中的相应名称
// - 新加入的成员被当作一般成员, 除非编译器提供特殊支持
typedef __false_type has_trivial_default_constructor;
typedef __false_type has_trivial_copy_constructor;
typedef __false_type has_trivial_assignment_operator;
typedef __false_type has_trivial_destructor;
typedef __false_type is_POD_type;
};
// 特化类型:
// char, signed char, unsigned char,
// short, unsigned short
// int, unsigned int
// long, unsigned long
// float, double, long double
/**
* 以下针对C++内置的基本数据类型提供特化版本,
* 使其具有trivial default constructor,
* copy constructor, assignment operator, destructor并标记其为POD类型
*/
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对char的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对unsigned char的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对short的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对unsigned short的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对int的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对unsigned int的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对long的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对unsigned long的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对float的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对double的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
//针对long double的特化版本
__STL_TEMPLATE_NULL struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
// 针对指针提供特化
template
struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
// 针对char *, signed char *, unsigned char *提供特化
struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
struct __type_traits
{
typedef __true_type has_trivial_default_constructor;
typedef __true_type has_trivial_copy_constructor;
typedef __true_type has_trivial_assignment_operator;
typedef __true_type has_trivial_destructor;
typedef __true_type is_POD_type;
};
九、自定义简单迭代器的实现
STL中每个容器都有自己的迭代器,各种迭代器的接口相同,内部实现却不相同,这也直接体现了泛型编程的概念,下面在单链表类中内嵌入一个iterator的类来实现单链表的迭代
#include
template
struct ListNode {
T value;
ListNode* next;
ListNode() {
next = 0;
}
ListNode(T val, ListNode *p = nullptr) :
value(val), next(p) {
}
};
template
class List {
private:
ListNode *m_pHead;
ListNode *m_pTail;
int m_nSize;
public:
List() {
m_pHead = nullptr;
m_pTail = nullptr;
m_nSize = 0;
}
//从链表尾部插入元素
void push_back(T value) {
if (m_pHead == nullptr) {
m_pHead = new ListNode(value);
m_pTail = m_pHead;
} else {
m_pTail->next = new ListNode(value);
m_pTail = m_pTail->next;
}
}
//打印链表元素
void print(std::ostream &os = std::cout) const {
for (ListNode *ptr = m_pHead; ptr != m_pTail->next ; ptr = ptr->next)
std::cout << ptr->value << " ";
os << std::endl;
}
//内置迭代器
class iterator {
private:
ListNode *m_ptr;
public:
iterator(ListNode* p = nullptr) :
m_ptr(p) {
}
T operator*() const {
return m_ptr->value;
}
ListNode* operator->() const {
return m_ptr;
}
iterator& operator++() {
m_ptr = m_ptr->next;
return *this;
}
iterator operator++(int) {
ListNode* tmp = m_ptr;
m_ptr = m_ptr->next;
return iterator(tmp);
}
bool operator==(const iterator &arg) const {
return arg.m_ptr == this->m_ptr;
}
bool operator!=(const iterator &arg) const {
return arg.m_ptr != this->m_ptr;
}
};
//返回链表头部指针
iterator begin() const {
return iterator(m_pHead);
}
//返回链表尾部指针
iterator end() const {
return iterator(m_pTail->next);
}
//其它成员函数
};
int main() {
List l;
l.push_back(1);
l.push_back(2);
l.print();
for (List::iterator it = l.begin(); it != l.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
十、STL源码学习
stl_iterator_base.h
/// This file contains all of the general iterator-related utilities.
/// The internal file stl_iterator.h contains predefined iterators,
/// such as front_insert_iterator and istream_iterator.
#include
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
///这些迭代器类型并非C++ Standard,客户端系自己的迭代器时
///可以根据属性继承这些类,以便拥有迭代器需具备的基本属性
///方可使得自定义迭代器与STL算法融合
template struct input_iterator {
typedef input_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
struct output_iterator {
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
};
template struct forward_iterator {
typedef forward_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
template struct bidirectional_iterator {
typedef bidirectional_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
template 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;
};
///对这些迭代器重要属性的型别推导函数
template
inline input_iterator_tag
iterator_category(const input_iterator<_Tp, _Distance>&)
{ return input_iterator_tag(); }
inline output_iterator_tag iterator_category(const output_iterator&)
{ return output_iterator_tag(); }
template
inline forward_iterator_tag
iterator_category(const forward_iterator<_Tp, _Distance>&)
{ return forward_iterator_tag(); }
template
inline bidirectional_iterator_tag
iterator_category(const bidirectional_iterator<_Tp, _Distance>&)
{ return bidirectional_iterator_tag(); }
template
inline random_access_iterator_tag
iterator_category(const random_access_iterator<_Tp, _Distance>&)
{ return random_access_iterator_tag(); }
template
inline random_access_iterator_tag iterator_category(const _Tp*)
{ return random_access_iterator_tag(); }
template
inline _Tp* value_type(const input_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }
template
inline _Tp* value_type(const forward_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }
template
inline _Tp* value_type(const bidirectional_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }
template
inline _Tp* value_type(const random_access_iterator<_Tp, _Distance>&)
{ return (_Tp*)(0); }
template
inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); }
template
inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}
template
inline _Distance* distance_type(const forward_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}
template
inline _Distance*
distance_type(const bidirectional_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}
template
inline _Distance*
distance_type(const random_access_iterator<_Tp, _Distance>&)
{
return (_Distance*)(0);
}
template
inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); }
///iterator_traits使得Tp*和const Tp*可以再STL中用到任何需要迭代器的地方
template
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;
};
template
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
struct iterator_traits {
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};
///对通用迭代器求距离,采用了型别推导,这是STL非常常见的一种
///泛型编程技法
template
inline void __distance(_InputIterator __first, _InputIterator __last,
_Distance& __n, input_iterator_tag)
{
while (__first != __last) { ++__first; ++__n; }
}
template
inline void __distance(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Distance& __n, random_access_iterator_tag)
{
///对型别的检验,使得在编译器发现问题,而非在运行期导致程序崩溃
///检验型别是否确实为随机迭代器
__STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);
__n += __last - __first;
}
template
inline void distance(_InputIterator __first,
_InputIterator __last, _Distance& __n)
{
__STL_REQUIRES(_InputIterator, _InputIterator);
///调用型别推导函数iterator_category得到迭代器的属性,从而调用合适的求距离函数
///为了或得效率(具有random_access_iterator_tag的迭代器求距离可以采用更具效率的做法)
__distance(__first, __last, __n, iterator_category(__first));
}
template
inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) {
while (__n--) ++__i;
}
template
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
inline void __advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag) {
__STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);
__i += __n;
}
template
inline void advance(_InputIterator& __i, _Distance __n) {
__STL_REQUIRES(_InputIterator, _InputIterator);
__advance(__i, __n, iterator_category(__i));
}
stl_iterator.h
///back_insert_iterator通过保存需要插入元素的容器指针
///每次容器元素的插入实际是调用其push_back成员函数实现的
///因此该容器必须具备push_back成员函数.
#include
template
class back_insert_iterator {
protected:
_Container* container;
public:
typedef _Container container_type;
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) {}
back_insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value) {
container->push_back(__value); ///每次为其赋值都调用绑定容器的push_back函数
return *this;
}
back_insert_iterator<_Container>& operator*() { return *this; }
back_insert_iterator<_Container>& operator++() { return *this; }
back_insert_iterator<_Container>& operator++(int) { return *this; }
};
template
inline output_iterator_tag
iterator_category(const back_insert_iterator<_Container>&)
{
return output_iterator_tag();
}
///实际更经常使用这个函数
template
inline back_insert_iterator<_Container> back_inserter(_Container& __x) {
return back_insert_iterator<_Container>(__x);
}
///除了调用push_front函数外,与back_insert_iterator如出一辙
template
class front_insert_iterator {
protected:
_Container* container;
public:
typedef _Container container_type;
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
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_insert_iterator<_Container>& operator*() { return *this; }
front_insert_iterator<_Container>& operator++() { return *this; }
front_insert_iterator<_Container>& operator++(int) { return *this; }
};
template
inline output_iterator_tag
iterator_category(const front_insert_iterator<_Container>&)
{
return output_iterator_tag();
}
template
inline front_insert_iterator<_Container> front_inserter(_Container& __x) {
return front_insert_iterator<_Container>(__x);
}
///提供插入位置的插入迭代器,调用绑定容器的insert函数
template
class insert_iterator {
protected:
_Container* container;
typename _Container::iterator iter;
public:
typedef _Container container_type;
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
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<_Container>& operator*() { return *this; }
insert_iterator<_Container>& operator++() { return *this; }
insert_iterator<_Container>& operator++(int) { return *this; }
};
template
inline output_iterator_tag
iterator_category(const insert_iterator<_Container>&)
{
return output_iterator_tag();
}
template
inline
insert_iterator<_Container> inserter(_Container& __x, _Iterator __i)
{
typedef typename _Container::iterator __iter;
return insert_iterator<_Container>(__x, __iter(__i));
}
/// This is the new version of reverse_iterator, as defined in the
/// draft C++ standard. It relies on the iterator_traits template,
/// which in turn relies on partial specialization. The class
/// reverse_bidirectional_iterator is no longer part of the draft
/// standard, but it is retained for backward compatibility.
template
class reverse_iterator
{
protected:
_Iterator current;
public:
///反向迭代器的各项性质型别与基迭代器保持一致
typedef typename iterator_traits<_Iterator>::iterator_category
iterator_category;
typedef typename iterator_traits<_Iterator>::value_type
value_type;
typedef typename iterator_traits<_Iterator>::difference_type
difference_type;
typedef typename iterator_traits<_Iterator>::pointer
pointer;
typedef typename iterator_traits<_Iterator>::reference
reference;
typedef _Iterator iterator_type;
typedef reverse_iterator<_Iterator> _Self;
public:
reverse_iterator() {}
explicit reverse_iterator(iterator_type __x) : current(__x) {}
reverse_iterator(const _Self& __x) : current(__x.current) {}
iterator_type base() const { return current; }
reference operator*() const {
///由于STL中所有区间都是左闭右开区间,因此对反向迭代器的提领需要在
///基迭代器的基础上后退一步再提领,才不至于提领到非法指针
_Iterator __tmp = current;
return *--__tmp;
}
pointer operator->() const { return &(operator*()); }
_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;
}
_Self operator+(difference_type __n) const {
return _Self(current - __n);
}
_Self& operator+=(difference_type __n) {
current -= __n;
return *this;
}
_Self operator-(difference_type __n) const {
return _Self(current + __n);
}
_Self& operator-=(difference_type __n) {
current += __n;
return *this;
}
reference operator[](difference_type __n) const { return *(*this + __n); }
};
template
inline bool operator==(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y) {
return __x.base() == __y.base();
}
template
inline bool operator<(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y) {
return __y.base() < __x.base();
}
template
inline typename reverse_iterator<_Iterator>::difference_type
operator-(const reverse_iterator<_Iterator>& __x,
const reverse_iterator<_Iterator>& __y) {
return __y.base() - __x.base();
}
template
inline reverse_iterator<_Iterator>
operator+(typename reverse_iterator<_Iterator>::difference_type __n,
const reverse_iterator<_Iterator>& __x) {
return reverse_iterator<_Iterator>(__x.base() - __n);
}
///istream_iterator类的声明,后面operator==要用到
template
class istream_iterator;
///operator==函数必须提前声明,否则不能作为istream_iterator类的友元函数出现
template
inline bool operator==(const istream_iterator<_Tp, _Dist>&,
const istream_iterator<_Tp, _Dist>&);
///istream_iterator类通过封装一个istream类型的指针来实现对istream流的操作
template
class istream_iterator {
friend bool operator==<>(const istream_iterator&,
const istream_iterator&);
protected:
istream* _M_stream;
_Tp _M_value; ///写入的数据类型
bool _M_end_marker; ///流结束标志
void _M_read() {
///先判断流是否结束,并重置结束标志
_M_end_marker = (*_M_stream) ? true : false;
///若尚未结束,读取一个对象
if (_M_end_marker) *_M_stream >> _M_value;
///再次重置流结束标志
_M_end_marker = (*_M_stream) ? true : false;
}
public:
typedef input_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Dist difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
///默认关联cin,并且处于流结束处
istream_iterator() : _M_stream(&cin), _M_end_marker(false) {}
///创建流对象时,调用read,试图读入一个对象
istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); }
reference operator*() const { return _M_value; }
pointer operator->() const { return &(operator*()); }
istream_iterator<_Tp, _Dist>& operator++() {
///迭代器每前进一步,调用一次read函数,试图读取一个对象
_M_read();
return *this;
}
istream_iterator<_Tp, _Dist> operator++(int) {
istream_iterator<_Tp, _Dist> __tmp = *this;
_M_read();
return __tmp;
}
};
template
inline input_iterator_tag
iterator_category(const istream_iterator<_Tp, _Dist>&)
{
return input_iterator_tag();
}
template
inline _Tp*
value_type(const istream_iterator<_Tp, _Dist>&) { return (_Tp*) 0; }
template
inline _Dist*
distance_type(const istream_iterator<_Tp, _Dist>&) { return (_Dist*)0; }
template
inline bool operator==(const istream_iterator<_Tp, _Distance>& __x,
const istream_iterator<_Tp, _Distance>& __y) {
return (__x._M_stream == __y._M_stream &&
__x._M_end_marker == __y._M_end_marker) ||
__x._M_end_marker == false && __y._M_end_marker == false;
}
///基本和istream实现相同,无结束标示符
template
class ostream_iterator {
protected:
ostream* _M_stream;
const char* _M_string; ///输出时用于分隔不同对象,有客户端提供
public:
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {}
ostream_iterator(ostream& __s, const char* __c)
: _M_stream(&__s), _M_string(__c) {}
ostream_iterator<_Tp>& operator=(const _Tp& __value) {
*_M_stream << __value;
if (_M_string) *_M_stream << _M_string;
return *this;
}
ostream_iterator<_Tp>& operator*() { return *this; }
ostream_iterator<_Tp>& operator++() { return *this; }
ostream_iterator<_Tp>& operator++(int) { return *this; }
};
template
inline output_iterator_tag
iterator_category(const ostream_iterator<_Tp>&) {
return output_iterator_tag();
}