STL源码解析(2) -- 迭代器iterator与traits

来源:互联网 发布:3d大型网络手机游戏 编辑:程序博客网 时间:2024/06/18 05:28

迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。

STL的核心思想在于将数据容器和算法解耦,使得容器和算法有很好的泛型能力,而iterator则在二者之间扮演着胶水的作用,适合二者能够紧密的结合在一起。


STL中iterator类型

根据STL中的分类,iterator包括:

  • Input Iterator:只能单步向前迭代元素,不允许修改由该类迭代器引用的元素。
  • Output Iterator:该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不同的是该类迭代器对元素只有写的权力。
  • Forward Iterator:该类迭代器可以在一个正确的区间中进行读写操作,它拥有Input
    Iterator的所有特性,和Output Iterator的部分特性,以及单步向前迭代元素的能力。
  • Bidirectional Iterator:该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力。
  • Random Access Iterator:该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。

继承关系如下图

继承关系如下图


iterator在STL中的定义

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 {};/**做为实现重载机制的标志符, 仅仅起到区分不同类型iterator的作用*同时不会占用任何资源*/template <class T, class Distance> struct input_iterator {    typedef input_iterator_tag iterator_category;    typedef T                  value_type;    typedef Distance           difference_type;    typedef T*                 pointer;    typedef T&                 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 T, class Distance> struct forward_iterator {    typedef forward_iterator_tag iterator_category;    typedef T                    value_type;    typedef Distance             difference_type;    typedef T*                   pointer;    typedef T&                   reference;};template <class T, class Distance> struct bidirectional_iterator {    typedef bidirectional_iterator_tag iterator_category;    typedef T                          value_type;    typedef Distance                   difference_type;    typedef T*                         pointer;    typedef T&                         reference;};template <class T, class Distance> struct random_access_iterator {    typedef random_access_iterator_tag iterator_category;    typedef T                          value_type;    typedef Distance                   difference_type;    typedef T*                         pointer;    typedef T&                         reference;};/* *迭代器定义5个型别,任何符合STL规范的iterator都需要定义这5个型别 */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;};

Iterator_traits

对iterator_traits传入任何一个迭代器都可以很轻松的获取iterator的类型以及各种属性
traits编程技巧大量用于STL的实现当中,利用内嵌型别与编译器的template参数推导功能增强了C++未能提供的关于型别认证方面的能力

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;}; /**对传入原生指针为T* 或者 const T*的特化模板*/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;};template <class T>struct iterator_traits<const T*> {  typedef random_access_iterator_tag iterator_category;  typedef T                          value_type;  typedef ptrdiff_t                  difference_type;  typedef const T*                   pointer;  typedef const T&                   reference;};//大量关于不同类型迭代器所实现的重载函数template <class Iterator>inline typename iterator_traits<Iterator>::iterator_categoryiterator_category(const Iterator&) {  typedef typename iterator_traits<Iterator>::iterator_category category;  return category();}template <class Iterator>inline typename iterator_traits<Iterator>::difference_type*distance_type(const Iterator&) {  return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);}template <class Iterator>inline typename iterator_traits<Iterator>::value_type*value_type(const Iterator&) {  return static_cast<typename iterator_traits<Iterator>::value_type*>(0);}template <class T, class Distance>inline input_iterator_tagiterator_category(const input_iterator<T, Distance>&) {  return input_iterator_tag();}inline output_iterator_tag iterator_category(const output_iterator&) {  return output_iterator_tag();}template <class T, class Distance>inline forward_iterator_tagiterator_category(const forward_iterator<T, Distance>&) {  return forward_iterator_tag();}template <class T, class Distance>inline bidirectional_iterator_tagiterator_category(const bidirectional_iterator<T, Distance>&) {  return bidirectional_iterator_tag();}template <class T, class Distance>inline random_access_iterator_tagiterator_category(const random_access_iterator<T, Distance>&) {  return random_access_iterator_tag();}template <class T>inline random_access_iterator_tag iterator_category(const T*) {  return random_access_iterator_tag();}template <class T, class Distance>inline T* value_type(const input_iterator<T, Distance>&) {  return (T*)(0);}template <class T, class Distance>inline T* value_type(const forward_iterator<T, Distance>&) {  return (T*)(0);}template <class T, class Distance>inline T* value_type(const bidirectional_iterator<T, Distance>&) {  return (T*)(0);}template <class T, class Distance>inline T* value_type(const random_access_iterator<T, Distance>&) {  return (T*)(0);}template <class T>inline T* value_type(const T*) { return (T*)(0); }template <class T, class Distance>inline Distance* distance_type(const input_iterator<T, Distance>&) {  return (Distance*)(0);}template <class T, class Distance>inline Distance* distance_type(const forward_iterator<T, Distance>&) {  return (Distance*)(0);}template <class T, class Distance>inline Distance*distance_type(const bidirectional_iterator<T, Distance>&) {  return (Distance*)(0);}template <class T, class Distance>inline Distance*distance_type(const random_access_iterator<T, Distance>&) {  return (Distance*)(0);}template <class T>inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }template <class T, class Distance>inline Distance* distance_type(const forward_iterator<T, Distance>&) {  return (Distance*)(0);}template <class T, class Distance>inline Distance*distance_type(const bidirectional_iterator<T, Distance>&) {  return (Distance*)(0);}template <class T, class Distance>inline Distance*distance_type(const random_access_iterator<T, Distance>&) {  return (Distance*)(0);}template <class T>inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }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 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_typedistance(InputIterator first, InputIterator last) {  typedef typename iterator_traits<InputIterator>::iterator_category category;  return __distance(first, last, category());}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_typedistance(InputIterator first, InputIterator last) {  typedef typename iterator_traits<InputIterator>::iterator_category category;  return __distance(first, last, category());}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(BidirectionalIterator& 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) {  __advance(i, n, iterator_category(i));}
原创粉丝点击