迭代器是什么

迭代器是用来访问容器(保存元素的数据结构)中的元素,也就是访问某种数据结构中的元素,是一种检查容器内元素并遍历元素的数据类型。 Iterator模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的方法)访问聚合对象中的各个元素。数组范围内的指针就是迭代器的一种。

指针针是C语言里面就有的东西,而迭代器是C++里面才有的。
指针通常用来访问的是序列的元素,但不是所有的容器都会在连续的内存空间上保存数据。所以,对于这些容器我们不能单纯地使用指针作为迭代器,而是针对每一种容器,都会有专门配对的迭代器。

对于所有的迭代器,它们的使用方法和指针一样,比如自增(++),解引用(*)。除了数组以外,在大部分的容器中都会提供成员函数beget()(在类中创建,类是C++中对于C语言中的结构体的延伸),用来获取容器开始位置的迭代器,会提供成员函数end(),用来获取容器结束位置的迭代器。

什么是迭代器?迭代器有什么作用?

迭代器类型

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

vector 和deque提供的是RandomAccessIterator,list提供的是BidirectionalIterator,set和map提供的 iterators是 ForwardIterator。
关于STL中iterator迭代器的操作如下:
说明:每种迭代器均可进行包括表中前一种迭代器可进行的操作。
迭代器操作 说明
(1)所有迭代器
p++ 后置自增迭代器
++p 前置自增迭代器
(2)输入迭代器
*p 复引用迭代器,作为右值
p=p1 将一个迭代器赋给另一个迭代器
p==p1 比较迭代器的相等性
p!=p1 比较迭代器的不等性
(3)输出迭代器
*p 复引用迭代器,作为左值
p=p1 将一个迭代器赋给另一个迭代器
(4)正向迭代器
提供输入输出迭代器的所有功能
(5)双向迭代器
–p 前置自减迭代器
p-- 后置自减迭代器
(6)随机迭代器
p+=i 将迭代器递增i位
p-=i 将迭代器递减i位
p+i 在p位加i位后的迭代器
p-i 在p位减i位后的迭代器
p[i] 返回p位元素偏离i位的元素引用
p<p1 如果迭代器p的位置在p1前,返回true,否则返回false
p<=p1 p的位置在p1的前面或同一位置时返回true,否则返回false
p>p1 如果迭代器p的位置在p1后,返回true,否则返回false
p>=p1 p的位置在p1的后面或同一位置时返回true,否则返回false
只有顺序容器和关联容器支持迭代器遍历,各容器支持的迭代器的类别如下:
容器 支持的迭代器类别 容器 支持的迭代器类别 容器 支持的迭代器类别
vector 随机访问 deque 随机访问 list 双向
set 双向 multiset 双向 map 双向
multimap 双向 stack 不支持 queue 不支持
priority_queue 不支持

Iterator模式有三个重要的作用:
1)迭代器支持以不同的方式遍历一个聚合.复杂的聚合可用多种方式进行遍历,如二叉树的遍历,可以采用前序、中序或后序遍历(以不同的顺序遍历了二叉树中的所有元素)。迭代器模式使得改变遍历算法变得很容易: 仅需用一个不同的迭代器的实例代替原先的实例即可,你也可以自己定义迭代器的子类以支持新的遍历,或者可以在遍历中增加一些逻辑,如有条件的遍历等。
2)迭代器简化了聚合的接口. 有了迭代器的遍历接口,聚合本身就不再需要类似的遍历接口了,这样就简化了聚合的接口。
3)在同一个聚合上可以有多个遍历 每个迭代器保持它自己的遍历状态,因此你可以同时进行多个遍历。
4)此外,Iterator模式可以为遍历不同的聚合结构(需拥有相同的基类)提供一个统一的接口,即支持多态迭代。
c++迭代器(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 {};

从迭代器模版看迭代器的具体结构
利用内嵌类型申明typedef可以轻松实现隐藏所指对象类型

// iterator 模板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 Pointer                              pointer;//指向迭代器所指向的元素的指针typedef Reference                            reference;//对迭代器所指向的元素的引用typedef Distance                             difference_type;//两个迭代器之间的距离};

C++:从类模板 Iterator 中的模板参数来看迭代器

迭代器的萃取

判断有无迭代器类型

 template <class T>struct has_iterator_cat//判断是否有迭代器类别iterator_category{private:struct two { char a; char b; };template <class U> static two test(...);//没有类别返回结构体twotemplate <class U> static char test(typename U::iterator_category* = 0);//有类别返回char//通过传入的模板类型有无typename U::iterator_category来返回two 还是charpublic:static const bool value = sizeof(test<T>(0)) == sizeof(char);//有类别返回true};

有类型就继承iterator_traits_impl()

template <class Iterator, bool>struct iterator_traits_impl {};template <class Iterator>struct iterator_traits_impl<Iterator, true>{typedef typename Iterator::iterator_category iterator_category;typedef typename Iterator::value_type        value_type;typedef typename Iterator::pointer           pointer;typedef typename Iterator::reference         reference;typedef typename Iterator::difference_type   difference_type;};

判断Iterator::iterator_category是否可以隐式转换为输入迭代器或输入迭代器,如果不能隐式转换也就没必要萃取了,如果能转换就得到所有迭代器信息。

template <class Iterator, bool>struct iterator_traits_helper {};template <class Iterator>struct iterator_traits_helper<Iterator, true>: public iterator_traits_impl<Iterator,std::is_convertible<typename Iterator::iterator_category, input_iterator_tag>::value ||std::is_convertible<typename Iterator::iterator_category, output_iterator_tag>::value>//判断Iterator::iterator_category是否可以隐式转换为输入迭代器或输入迭代器{};

判断迭代器具体类型

 //T类型迭代器能隐式转换为U类型迭代器template <class T, class U, bool = has_iterator_cat<iterator_traits<T>>::value>struct has_iterator_cat_of: public m_bool_constant<std::is_convertible<typename iterator_traits<T>::iterator_category, U>::value>//判断T类型迭代器能隐式转换为U类型迭代器{};//T类型迭代器无法隐式转换为U类型迭代器 template <class T, class U>struct has_iterator_cat_of<T, U, false> : public m_false_type {};//判断是否为input_iterator_tag类别迭代器template <class Iter>struct is_input_iterator : public has_iterator_cat_of<Iter, input_iterator_tag> {};//判断是否为output_iterator_tag类别迭代器template <class Iter>struct is_output_iterator : public has_iterator_cat_of<Iter, output_iterator_tag> {};//判断是否为forward_iterator_tag类别迭代器template <class Iter>struct is_forward_iterator : public has_iterator_cat_of<Iter, forward_iterator_tag> {};//判断是否为bidirectional_iterator_tag类别迭代器template <class Iter>struct is_bidirectional_iterator : public has_iterator_cat_of<Iter, bidirectional_iterator_tag> {};//判断是否为random_access_iterator_tag类别迭代器template <class Iter>struct is_random_access_iterator : public has_iterator_cat_of<Iter, random_access_iterator_tag> {};//判断是否为迭代器,所有迭代器都是从input_iterator_tag 和 output_iterator_tag派生来的 ,所以只要判断是否是input_iterator_tag 或 output_iterator_tagtemplate <class Iterator>struct is_iterator :public m_bool_constant<is_input_iterator<Iterator>::value ||is_output_iterator<Iterator>::value>{};

泛型算法,得到某个迭代器某个特性的类型
C++类型萃取(traits)技术

C++ 模板类型萃取技术 traits

// 萃取某个迭代器的 category,返回的就是结构体中的类型template <class Iterator>typename iterator_traits<Iterator>::iterator_categoryiterator_category(const Iterator&){typedef typename iterator_traits<Iterator>::iterator_category Category;//把iterator_traits<Iterator>::iterator_category类型命名为Categoryreturn Category();}// 萃取某个迭代器的 distance_typetemplate <class Iterator>typename iterator_traits<Iterator>::difference_type*distance_type(const Iterator&)// 在开头的迭代器结构体中定义过,typename iterator_traits<Iterator>::difference_type*就是迭代器之间的距离距离{return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);}// 萃取某个迭代器的 value_typetemplate <class Iterator>typename iterator_traits<Iterator>::value_type*value_type(const Iterator&){return static_cast<typename iterator_traits<Iterator>::value_type*>(0);

MyTinySTL阅读笔记—迭代器

通过迭代器类型的应用:计算距离、移动迭代器

template <class InputIterator>
typename iterator_traits<InputIterator>::difference_type distance(InputIterator first, InputIterator last)
{// 按照迭代器种类分类处理return distance_dispatch(first, last, iterator_category(first));
}/*! 计算first迭代器和last迭代器之间的距离 input_iterator_tag版本 按照链表的方式计算 */
template <class InputIterator>
typename iterator_traits<InputIterator>::difference_type distance_dispatch(InputIterator first, InputIterator last, input_iterator_tag)
{typename iterator_traits<InputIterator>::difference_type n = 0;while (first != last){++first;++n;}return n;
}/*! 计算first迭代器和last迭代器之间的距离 random_access_iterator_tag版本 按照指针的方式计算 */
template <class RandomIter>
typename iterator_traits<RandomIter>::difference_type distance_dispatch(RandomIter first, RandomIter last, random_access_iterator_tag)
{return last - first;
}

迭代器Iterator相关推荐

  1. C++中的迭代器(STL迭代器)iterator

    1.Cpp中的迭代器 要访问顺序容器和关联容器中的元素,需要通过迭代器(iterator)进行.迭代器是一个变量,相当于容器和操纵容器的算法之间的中介.迭代器可以指向容器中的某个元素,通过迭代器就可以 ...

  2. c++迭代器iterator通用吗_「ES6基础」迭代器(iterator)

    迭代器(iterator)是一个结构化的模式,用于从源以一次一个的方式提取数据.迭代器的使用可以极大地简化数据操作,于是ES6也向JS中添加了这个迭代器特性.新的数组方法和新的集合类型(如Set集合与 ...

  3. 如何得到iterator的当前元素_Java中迭代器Iterator详解

    1.定义 Iterator的定义为:对Collection进行迭代的迭代器,Iterator取代了Java Collection Framework中的Enumeration.Iterator与Enu ...

  4. C++ - const 与 迭代器(iterator) 使用 详解

    const 与 迭代器(iterator) 使用 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/16030561 迭代器(i ...

  5. java:迭代器Iterator

    迭代器Iterator是一个对象,它的工作是遍历并选择序列中的对象,它提供了一种访问一个容器(container)对象中的各个元素,而不必暴露该对象内部细节的方法. 通过容器的 iterator()方 ...

  6. Java迭代器Iterator接口

    迭代器 Iterator接口 迭代器的代码实现 增强for循环 Iterator接口 java.util.Iterator接口:(对集合进行遍历) 有两个常用方法 1.boolean hasNext( ...

  7. java for 迭代器_Java基础-迭代器Iterator与语法糖for-each

    迭代器Iterator与语法糖for-each 一.为什么需要迭代器 设计模式迭代器 迭代器作用于集合,是用来遍历集合元素的对象.迭代器不是Java独有的,大部分高级语言都提供了迭代器来遍历集合.实际 ...

  8. Python中生成器generator和迭代器Iterator的使用方法

    一.生成器 1. 生成器的定义 把所需要值得计算方法储存起来,不会先直接生成数值,而是等到什么时候使用什么时候生成,每次生成一个,减少计算机占用内存空间 2. 生成器的创建方式 第一种只要把一个列表生 ...

  9. java 迭代器的原理_Java集合框架迭代器Iterator实现原理解析

    使用循环遍历集合 普通for循环 for(int i=0;i<10;i++){} 增强for循环 for(String str:list){} 什么是迭代器Iterator Iterator是J ...

  10. STL源码剖析 迭代器iterator的概念 和 traits编程技法

    iterator模式定义如下:提供一种方法,使之能够依序巡访某个 聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表述方式. STL的中心思想在于:将数据容器(containers)和算法(a ...

最新文章

  1. 节后综合征疗愈神器,这个开源项目帮你10分钟上手AI算法开发!
  2. 二分查找(递归和非递归)
  3. 自制贴纸图案大全图片_重磅!Supreme x 山本耀司联名Bogo贴纸泄露,发售确认?!...
  4. 它来了,它来了,最强目标检测算法YOLO v4,它真的来了!!!
  5. 字符流---IO学习笔记(三)
  6. 2015蓝桥杯省赛---java---C---1(隔行变色)
  7. revit2018注册表删除_Revit软件的彻底卸载方法 注册表卸载
  8. 苹果第三代iPhone SE或将于12月份开始投产 明年春季发布
  9. php acl,php – 访问控制和XHR请求
  10. linux光驱安装内核,Linux的内核管理--之光盘恢复grub的方法
  11. [在职软件工程]面向对象的分析与设计
  12. php添加pdo_mysql_php下添加pdo_mysql扩展
  13. rubyinstaller官网无法访问的解决办法
  14. 数学模型预测模型_改进著名的nfl预测模型
  15. 中国信通院:5G无人机应用白皮书
  16. 图片如何抠图换背景?怎样将图片抠成透明底图片?
  17. 12.27追求世俗意义上的成功与心灵快感的矛盾
  18. linux网桥的简单理解和配置
  19. 【约瑟夫环】Java实现:100个人开始从1开始报数,每当报数到3,报数3的人离开,求最后留下来人的位置。
  20. java maven 引入有赞云SDK

热门文章

  1. 快上车!攻击全球电视、银行大盗火线追踪、黑客篡改支付金额,雷锋网带你闯进 SyScan 360...
  2. 小项目:简易社区制作
  3. Mac 终端配置代理
  4. cursor is oracle 日期_Oracle 12CR2查询转换之cursor-duration临时表
  5. 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准
  6. 小学计算机的组成微格教案,微格教学教案-计算机
  7. 如何能布局出好楼盘风水 看楼盘风水如何布局助力翻盘
  8. 阿里巴巴北京总部鸟瞰图曝光 2024年投入使用
  9. springboot集成支付宝支付2.0
  10. 数据库编程-----数据库设计范式