# STL之迭代器

## 1 迭代器的分类与特点

1)input_iterator                                     只读

2)output_iterator                                   只写

3)forward_iterator                                  允许写入型算法在这种迭代器区间进行读写操作

4)bidirectional_iterator                           双向移动

5)random_access_iterator                      随机访问

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;
};

struct output_iterator {
typedef output_iterator_tag iterator_category;
typedef void                value_type;
typedef void                difference_type;
typedef void                pointer;
typedef void                reference;
};

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;
};

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;
};

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;
};

## 2 迭代器相应型别

template <class _Category, class _Tp, class _Distance = ptrdiff_t,
class _Pointer = _Tp*, class _Reference = _Tp&>
struct iterator {
typedef _Category  iterator_category;
typedef _Tp        value_type;
typedef _Distance  difference_type;
typedef _Pointer   pointer;
typedef _Reference reference;
};
iterator_category迭代器的类型标示,用于区分不同类别的迭代器,之所以将它定义为一种类类型,

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 {};

## 3 迭代器类型提取  --- traits技术

### 3.1 traints技术:

1) 模板参数推导机制

2) 偏特化技术    --- 解决以指针或常量指针实现的迭代器

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;
};

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;
};

### 3.2 提取不同型别的实现

template <class _Iter>
inline typename iterator_traits<_Iter>::iterator_category
__iterator_category(const _Iter&)
{
typedef typename iterator_traits<_Iter>::iterator_category _Category;
return _Category();
}

template <class _Iter>
inline typename iterator_traits<_Iter>::difference_type*
__distance_type(const _Iter&)
{
return static_cast<typename iterator_traits<_Iter>::difference_type*>(0);
}

template <class _Iter>
inline typename iterator_traits<_Iter>::value_type*
__value_type(const _Iter&)
{
return static_cast<typename iterator_traits<_Iter>::value_type*>(0);
}

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>::difference_type*
distance_type(const _Iter& __i) { return __distance_type(__i); }

template <class _Iter>
inline typename iterator_traits<_Iter>::value_type*
value_type(const _Iter& __i) { return __value_type(__i); }

### 4.1 distance

template <class _InputIterator, class _Distance>
inline void __distance(_InputIterator __first, _InputIterator __last,
_Distance& __n, input_iterator_tag)
{
while (__first != __last) { ++__first; ++__n; }
}

template <class _RandomAccessIterator, class _Distance>
inline void __distance(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Distance& __n, random_access_iterator_tag)
{
__n += __last - __first;
}

template <class _InputIterator, class _Distance>
inline void distance(_InputIterator __first,
_InputIterator __last, _Distance& __n)
{
__distance(__first, __last, __n, iterator_category(__first));
}

template <class _InputIter, class _Distance>
inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) {
while (__n--) ++__i;
}

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1183
#endif

template <class _BidirectionalIterator, class _Distance>
inline void __advance(_BidirectionalIterator& __i, _Distance __n,
bidirectional_iterator_tag) {
if (__n >= 0)
while (__n--) ++__i;
else
while (__n++) --__i;
}

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1183
#endif

template <class _RandomAccessIterator, class _Distance>
inline void __advance(_RandomAccessIterator& __i, _Distance __n,
random_access_iterator_tag) {
__i += __n;
}

template <class _InputIterator, class _Distance>
inline void advance(_InputIterator& __i, _Distance __n) {
}