STL源码剖析——iterators与trait编程#4 iterator源码
在前两节介绍了迭代器的五个相应类型,并讲述如何利用traits机制提取迭代器的类型,但始终是把iteartor_traits类分割开来讨论,这影响我们的理解,本节将给出iteator的部分源码,里面涵盖了整个iteartor_traits泛化版本、偏特化版本以及一些算法的完整代码。重新把先前讲的知识捋顺一下。
1 //节选自SGI STL<stl_iterator.h> 2 3 //五种迭代器类型,继承表示,越底层的基类越低级,越上层的子类越高级 4 struct input_iterator_tag {}; 5 struct output_iterator_tag {}; 6 struct forward_iterator_tag : public input_iterator_tag {}; 7 struct bidirectional_iterator_tag : public forward_iterator_tag {}; 8 struct random_access_iterator_tag : public bidirectional_iterator_tag {}; 9 10 //要使自己设计的迭代器符合STL的规范,最好继承自下面的std::iterator 11 template <class Category, class T, class Distance = ptrdiff_t, 12 class Pointer = T*, class Reference = T&> 13 struct iterator { 14 typedef Category iterator_category; 15 typedef T value_type; 16 typedef Distance difference_type; 17 typedef Pointer pointer; 18 typedef Reference reference; 19 }; 20 21 //提取迭代器五个相应类型的榨汁机iterator_traits,可以看到迭代器其特性均来自迭代器本身,说明设计迭代器时候就应该考虑提供这五个相应类型。所以为了防止自己设计时有所遗漏,继承std::iterator是上策 22 template <class Iterator> 23 struct iterator_traits { 24 typedef typename Iterator::iterator_category iterator_category; 25 typedef typename Iterator::value_type value_type; 26 typedef typename Iterator::difference_type difference_type; 27 typedef typename Iterator::pointer pointer; 28 typedef typename Iterator::reference reference; 29 }; 30 //针对原生指针而设计的traits偏特化版本 31 template <class T> 32 struct iterator_traits<T*> { 33 typedef random_access_iterator_tag iterator_category; 34 typedef T value_type; 35 typedef ptrdiff_t difference_type; 36 typedef T* pointer; 37 typedef T& reference; 38 }; 39 //针对原生pointer-to-const而设计的traits偏特化版本 40 template <class T> 41 struct iterator_traits<const T*> { 42 typedef random_access_iterator_tag iterator_category; 43 typedef T value_type; 44 typedef ptrdiff_t difference_type; 45 typedef const T* pointer; 46 typedef const T& reference; 47 }; 48 //全局函数,这个函数可以很方便地决定某个迭代器的类型 49 template <class Iterator> 50 inline typename iterator_traits<Iterator>::iterator_category 51 iterator_category(const Iterator&) { 52 typedef typename iterator_traits<Iterator>::iterator_category category; //使用traits机制提取其iterator category 53 return category(); 54 } 55 //全局函数,这个函数可以很方便地决定某个迭代器的distance type 56 template <class Iterator> 57 inline typename iterator_traits<Iterator>::difference_type* 58 distance_type(const Iterator&) { 59 return static_cast<typename iterator_traits<Iterator>::difference_type*>(0); 60 } 61 //全局函数,这个函数可以很方便地决定某个迭代器的value type 62 template <class Iterator> 63 inline typename iterator_traits<Iterator>::value_type* 64 value_type(const Iterator&) { 65 return static_cast<typename iterator_traits<Iterator>::value_type*>(0); 66 } 67 68 //整组distance函数,该函数有计算两迭代器距离的功能 69 template <class InputIterator, class Distance> 70 inline void __distance(InputIterator first, InputIterator last, Distance& n, 71 input_iterator_tag) { //如果是非随机迭代器,只能每次循环都要判断是否到达last迭代器 72 while (first != last) { ++first; ++n; } 73 } 74 75 template <class RandomAccessIterator, class Distance> 76 inline void __distance(RandomAccessIterator first, RandomAccessIterator last, 77 Distance& n, random_access_iterator_tag) { //随机迭代器,不用做两迭代器是否相同的比较,由于提供了operator-(),直接减法处理,速度比前者快 78 n += last - first; 79 } 80 81 template <class InputIterator, class Distance> 82 inline void distance(InputIterator first, InputIterator last, Distance& n) { 83 __distance(first, last, n, iterator_category(first)); //使用上面提到的iterator_category()全局函数决定哪个迭代器类型 84 } 85 86 //以下是整组advance函数,该函数具有从某迭代器出发跳跃到指定距离位置的功能 87 template <class InputIterator, class Distance> 88 inline void __advance(InputIterator& i, Distance n, input_iterator_tag) { 89 while (n--) ++i; //使用非随机单向迭代器,只能逐次前进至指定位置 90 } 91 92 template <class BidirectionalIterator, class Distance> 93 inline void __advance(BidirectionalIterator& i, Distance n, 94 bidirectional_iterator_tag) { //使用双向迭代器,可能往前或往后移动,但也是只能逐次移动至指定位置 95 if (n >= 0) 96 while (n--) ++i; 97 else 98 while (n++) --i; 99 } 100 101 template <class RandomAccessIterator, class Distance> 102 inline void __advance(RandomAccessIterator& i, Distance n, 103 random_access_iterator_tag) { //随机迭代器,真正的跳跃 104 i += n; 105 } 106 107 template <class InputIterator, class Distance> 108 inline void advance(InputIterator& i, Distance n) { 109 __advance(i, n, iterator_category(i)); //使用上面提到的iterator_category()全局函数决定哪个迭代器类型 110 }