迭代器分了五种类型,总共有五种迭代器相应型别
以下为源码:
//摘自SGI_STL <stl_iterator.h>
//五种迭代器类型
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 {};
这五个类只是作为标记用,不需要任何成员。
前三个只有operator++操作,第四个还有operator--操作,第五个包括p+n,p-n, p[n], p++, p--;
五种迭代器类型为:
//将五种相应型别定义到一个类中,自行开发的迭代器最好继承下面这个类
template <class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator
{
typedef Category iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
}
五种型别如下:
1) typedef Category iterator_category:定义的是迭代器类型,即如上五种类型
2) typedef T value_type; 迭代器所指的对象的类型
3) typedef Distance difference_type:两个迭代器之间的距离
4) typedef Pointer pointer: T*
5) typedef Reference reference:T&
而STL中iterator_traits实现机制,用一个专门的模板类来“萃取”迭代器的特性,traits意义是,如果I定义有做自己的value_type,则通过这个traits的作用,萃取出来的value_type就是I::value_type,对于不是类类型的迭代器,无法实现内嵌性别声明,则用iterator_traits的偏特化版本实现,如下源码:
//"榨汁机"traits
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;
}
//针对原生指针而设计的traits偏特化版
template <class T>
struct iterator_traits<T*>
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
}
//针对原生之pointer-to-const而设计的traits偏特化版
template <class Iterator>
struct iterator_traits<const T*>
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
}
以下函数可以很方便的决定某个迭代器的特定的前三种类别:
//这个函数可以很方便的决定某个迭代器的类型(category)
template <class Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&)
{
typedef typename iterator_traits<Iterator>::iterator_category category;
return category();
}
//这个函数可以很方便的决定某个迭代器的distance_type,是*,参数是引用
template <class Iterator>
inline typename iterator_traits<Iterator>::difference_type*
difference_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);
}
//这个函数可以很方便的决定某个迭代器的vlaue_type
template <class Iterator>
inline typename iterator_traits<Iterator>::value_type*
value_type(const Iterator&)
{
return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
}
以下为两个例子,分别是distance函数,和advance函数
//以下是整组distance函数
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type
__distance(InputIterator first, InputIterator last, input_iterator_tag)
{
iterator_traits<InputIterator>::difference_type n = 0;
while (first != last)
{
++first;
++n;
}
return n;
}
template <class RandomAccessIterator>
inline iterator_traits<RandomAccessIterator>::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag)
{
return last - first;
}
template <class InputIterator>
inline iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last)
{
typedef typename iterator_traits<InputIterator>::iterator_category category;
//利用函数重载,在编译时决定迭代器是哪种类型
return __distance(first, last, category());
}
//以下是整组advance函数
template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag)
{
while(n--)
++i;
}
template <class BidirectionalIterator, class Distance>
inline void __advance(BidrectionalIterator& i, Distance n, Bidirectional_iterator_tag)
{
if (n >= 0)
while (n--)
++i;
else
while (n++)
--i;
}
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)
{
//iterator_category决定i的迭代器类型,然后决定调用那个函数
__advance(i, n, iterator_category(i));
};