迭代器是将算法和容器两个独立的泛型进行调和的一个接口. 使咱们不须要关系中间的转化是怎么样的就都能直接使用迭代器进行数据访问. 而迭代器最重要的就是对operator *
和operator->
进行重载, 使它表现的像一个指针.算法
迭代器根据移动特性和实施操做被分为5类dom
- input iterator(输入迭代器) : 迭代器所指的内容不能被修改, 只读且只能执行一次读操做.
- output iterator(输出迭代器) : 只写而且一次只能执行一次写操做.
- forward iterator(正向迭代器) : 支持读写操做且支持屡次读写操做.
- bidirectional iterator(双向迭代器) : 支持双向的移动且支持屡次读写操做.
- random access iterator(随即访问迭代器) : 支持双向移动且支持屡次读写操做. p+n, p-n等.
1~4类迭代器执行操做的就如 : p++, ++p, p->而不是5类的p+n操做. 不明白的咱们下面会进行讲解.函数
category的五类迭代器以及继承关系源码分析
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 {};
这五个类都是空类, 只是为了以后调用时经过类选择不一样的重载函数. 继承是为了可使用传递调用,当不存在某种迭代器类型匹配时编译器会依据继承层次向上查找进行传递, 就能够经过继承关系来决定选择最优的调用. 咱们经过用distance
来说最优.指针
distance
是用于计算连个迭代器之间的距离, 由于重载就能够经过不一样的迭代器类型选择不一样的函数来提升效率.code
这里distance
的iterator_category
函数是每一个迭代器本身定义的, 跟traits
萃取器相关我准备放在下一篇章讲解. 这里只要知道它能经过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, 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; }
从distance
源码能够看出来不一样的迭代器的计算方式并不同, random_access_iterator_tag
的距离的计算效率最高, 其余都是经过++
操做来依次访问. 固然random_access_iterator_tag
类的迭代器也是能够调用input_iterator_tag
, 可是显然效率很低, 因此不一样的迭代器最本身最佳的效率. 经过iterator_category
进行最优选择.接口
五类迭代器的结构体, 能够看出来每一个类都定义了相同的变量名. 可是每一个名的类型不必定同样, 提供统一的名是为了traits
进行类型萃取. 每一个类的iterator_category
都是表明了不一样的迭代器, 经过它来选择该迭代器执行的函数.input
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; };
iterator_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(); }
这一篇仅仅只是讲解了一些关于迭代器类型, 和一点traits
的一点用法. 关于每一个迭代器都设置为相同的类型名都是为了traits
萃取器作准备. 下篇进行探讨.