STL源码剖析:Iterator

本文详细介绍了STL中的迭代器原理,包括迭代器需遵循的原则,其五种类型(input_iterator_tag,output_iterator_tag等),以及如何通过Traits机制提取迭代器的相关类型。着重展示了如何根据迭代器类型调用不同的处理函数。
摘要由CSDN通过智能技术生成

STL源码剖析:Iterator

Iterator需要遵循的原则

迭代器是算法和容器之间的桥梁

· 迭代器必须提供5种相关类型(associated types),以配合算法

Iterator的五种类型

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 {};
  • input_iterator_tag: 该种迭代器所指向类型只读

  • output_iterator_tag: 所指向类型只写

  • forward_iterator_tag:允许读写操作

  • bidirectional_iterator_tag:允许双向移动(++ 和 --)

  • random_iterator_tag: 允许跳跃访问

将迭代器设计成为继承式有一个好处是可以消除“单纯传递调用的函数”

对于没有指定类型对应的重载函数时,会调用参数类型为其父类的重载函数。

Iterator的5种associated types

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_category:迭代器的类别
  • value_type:迭代器所指向的对象的型别
  • difference_type:用来表示两个迭代器的距离,也可以用来表示一个容器的最大容量
  • pointer:所指向对象的型别的指针
  • reference:所指向对象的型别的引用

Traits (萃取机)

迭代器不一定是class,它有可能是native pointer,原生指针无法定义其关联类型,所以需要一个萃取机来分辨所得到的iterator是class还是native pointer,并利用partial specialization(偏特化)来得到其关联的类型。

萃取机的三个类别:

//萃取机 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;
};
//针对原生指针而设计的偏特化版
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 T*													pointer;
  typedef T&													reference;
};

通过traits获取迭代器相关型别的方法

  • 获取迭代器的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* distance_type(const Iterator&) {
  return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);
}
  • 获取迭代器的value 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);
}

根据迭代器的类型,调用不同处理函数的方法

对于外部接口,只接受迭代器和相关参数。然后在外部接口中,添加上迭代器的类型来调用重载函数。

例如:

//对外接口
template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n) {
	__advance(i, n iterator_category(i));
}

//以下为对内接口
template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
  ......
}

template <class BidirectionalIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, bidirectional_iterator_tag) {
  ......
}

template <class RandomAccessIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, random_access_iterator_tag) {
  ......
}

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值