迭代器分了五种类型,总共有五种迭代器相应型别
以下为源码:
//摘自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函数 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)); };