一、迭代器的种类

C++中的容器以及泛型算法会大量的使用迭代器

目前已经出现的迭代器有一下几种

1.输出迭代器 (OutputIterator)

输出迭代器类似于输出流(只能向输出流中写入数据),只能向输出迭代器中写入数据,输出迭代器的常用操作如下

2.输入迭代器 (InputIterator)

输入迭代器类似于输入流(变量只能读取输出流中的数据),只能向输出迭代器中写入数据,输入迭代器的常用操作如下

3.前向迭代器 (ForwardIterator)

加强版的输入迭代器,可以对前向迭代器进行赋值,如果一个前向迭代器不是const的,那么也具有输入迭代器的功能

C++标准库中的单向链表(forward_list)和无序容器的实现提供了前向迭代器,当然,无序容器也的实现也可以提供双向迭代器

4.双向迭代器 (BidirectionalIterator)

加强版的前向迭代器,提供了递减操作符,可以一步一步后退迭代器

在前向迭代器的基础上,新增的操作如下:

C++标准库中的双向链表(list)和关联容器的实现提供了双向迭代器

5.随机访问迭代器 (RandomAccessIterator)

加强版的双向迭代器,在双向迭代器的基础上增加了随机访问的能力,能够使迭代器增减某个偏移量,并且添加了比较操作

新增操作如下

C++标准库中的vector,deque,string以及指针提供了随机访问迭代器

使用随机访问迭代器时,需要注意不能让迭代器的位置超过end(),因为随机访问迭代器提供了前进n个元素的操作,所以在使用随机访问迭代器遍历容器的时,循环条件要写成it<container.end(),而不要写成it!=container.end(),因为迭代器作为循环变量有可能一次性前进n个元素,就像下图所示

上述五中迭代器,最最常用的是随机访问迭代器和双向迭代器,因为这两中迭代器由C++标准库中的主要容器提供使用,然后是前向迭代器,因为在使用迭代器时都是伴随这容器一起使用,所以输入输出迭代器一般情况用不到,在前面的博客中也会发现,输入输出迭代器一般用于指定容器成员函数和泛型算法函数的形参类型

二、五中迭代器的关系

1.所有前向,双向和随机访问迭代器也是有效的输入迭代器。

2.所有非const的前向,双向和随机访问迭代器也是有效的输出迭代器。

3.所有双向和随机访问迭代器也是有效的前向迭代器。

4.所有随机访问迭代器也是有效的双向迭代器。

5.就功能而言,随机访问迭代器是最完整的迭代器。 所有指针类型也是有效的随机访问迭代器。

上述五点中用图形来描述如下图

正是因为有上述关系,当我们使用C++标准库中以输入输出迭代器为形参的泛型算法函数或者容器的成员函数时,可以传入前向迭代器或者双向迭代器或者随机访问迭代器参数

同样,当我们使用C++标准库中以前向双向迭代器为形参的泛型算法函数或者容器的成员函数时,可以传入随机访问迭代器参数

当函数的返回值是一个输入或者输出迭代器,同样也可以用前向双向迭代器对象接收

三、迭代器相关的辅助函数

下面四个函数在使用前,要添加头文件 #include <iterator>

1.advance

template <class InputIterator, class Distance>
void advance (InputIterator& it, Distance n);

该函数可将迭代器it的位置增加,其中对于双向和随机访问迭代器来说,n有可能是负数,此时迭代器的位置后退,n的类型一般来说是整形

注意:该函数并不检查迭代器it是否超过了end(),所以有可能导致迭代器失效,所以使用前要判断是否小于end()

示例

void advancetest()
{vector<int> v={1,2,3,4,5,6,7};vector<int>::iterator it=v.begin()+3;advance(it, 2);if (it<v.end()) {cout<<*it<<endl;}it=v.begin()+3;advance(it, -2);if (it<v.end()) {cout<<*it<<endl;}
}

2.next和prev

template <class ForwardIterator>
ForwardIterator next (ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1);template <class BidirectionalIterator>
BidirectionalIterator prev (BidirectionalIterator it, typename iterator_traits<BidirectionalIterator>::difference_type n = 1);

next表示将迭代器的位置向前移动,如果it是一个双向迭代器或者是一个随机迭代器,那么n可以为负值,表示向后移动

prev表示将迭代器的位置向后移动,n可以为负值,表示向前移动

这两个函数依然不会保证迭代器有效,所以,调用者要自行保证这两个函数执行后,迭代器有效

示例

void nextprevtest()
{vector<int> v={1,2,3,4,5,6,7};vector<int>::iterator it=v.begin()+3;it=next(it, 2);if (it<v.end()) {cout<<*it<<endl;}it=prev(it,3);if (it<v.end()) {cout<<*it<<endl;}
}

3.distance

template<class InputIterator>
typename iterator_traits<InputIterator>::difference_type distance (InputIterator first, InputIterator last);

distance是计算并返回两个迭代器之间的距离,这两个迭代器必须指向同一个容器对象,如果first和last不是随机访问迭代器,那么,first前进必须能到达last,first必须在last之前或指向同一位置

示例

void distancetest()
{list<int> l={1,2,3,4,5,6,7};list<int>::iterator it1=l.begin();list<int>::iterator it2=l.end();int num=distance(it1,it2);cout<<num<<endl;
}

如果将第六行的代码改为int num=distance(it2,it1);,则会产生段错误

参考

《C++ Primer》

《C++标准库》

http://www.cplusplus.com/reference/iterator/

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

C++知识点28——使用C++标准库(再谈迭代器)相关推荐

  1. C++知识点19——使用C++标准库(再谈string——string的初始化、赋值、添加、删除、访问)

    1.string的构造函数 string();//默认构造函数,默认初始化时调用 string (const string& str);//拷贝构造函数,拷贝初始化时调用 string (si ...

  2. C++知识点21——使用C++标准库(再谈string——string的搜索和数值转化)

    string的搜索操作一共6个 1.find size_t find (const string& str, size_t pos = 0) const; //从调用对象的下标pos处开始查找 ...

  3. C++知识点32——使用C++标准库(关联容器set和multiset的初始化,赋值,查找,添加,删除与迭代器失效)

    关联容器map和multimap已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877和https://blog.csdn.ne ...

  4. C++知识点30——使用C++标准库(关联容器map及其初始化,赋值,查找,添加,删除与迭代器失效)

    一.关联容器简介 关于顺序容器和关联容器的区别已经在博客https://blog.csdn.net/Master_Cui/article/details/107427911中提过 C++标准库中的关联 ...

  5. C++知识点26——使用C++标准库(常用的泛型算法1)

    C++中实现了很多的泛型算法,大约100多个,使用前要添加#include<algorithm> 下面介绍的基本可以满足绝大部分需求,其他的用到再查 一.计数算法 1.count temp ...

  6. C++知识点23——使用C++标准库(顺序容器list的其他操作)

    除了博客https://blog.csdn.net/Master_Cui/article/details/107751785中介绍的操作,list还有一些其他的操作 1.reverse void re ...

  7. C++知识点33——使用C++标准库(无序关联容器unordered_(multi)map,unordered_(multi)set)

    C++中,无序关联容器一共有4个,unordered_map,unordered_set,unordered_multimap,unordered_multiset 这四个和有序关联容器最大的区别就是 ...

  8. C++知识点31——使用C++标准库(关联容器multimap及其初始化,赋值,查找,添加,删除与迭代器失效)

    关于关联容器map已经在博客https://blog.csdn.net/Master_Cui/article/details/108690877中介绍完了 multimap和map非常类似,容器中的元 ...

  9. C++知识点29——使用C++标准库(迭代器适配器)

    在上一篇文章https://blog.csdn.net/Master_Cui/article/details/108512730谈到的迭代器是基本的五种类型的迭代器 但是随着C++标准库的扩展,又实现 ...

最新文章

  1. win10 看不到其它计算机,w10网上邻居搜索不到其它电脑怎么办
  2. 数据库操作——多表查询
  3. laravel改代码没变化_推荐10个优质的Laravel扩展
  4. LeetCode 95. 不同的二叉搜索树 II(递归)
  5. leetcode 4 --- 寻找两个有序数组的中位数
  6. centos配置网络笔记
  7. tomcat temp 大量 upload 文件_问题:JavaWeb中实现文件上传的方式有哪些?
  8. 【Processing日常2】群星1
  9. qq代理服务器哪里获取_哪里可以下载小学英语课件?这3个渠道,英语老师得赶快收藏...
  10. 三十五岁后,就不能做软件测试了?
  11. 六石风格文档范例:做测试结果表格
  12. 回顾18年我的Java自动化测试框架
  13. racecar 尝试记录
  14. 2019年全国大学生电子设计竞赛赛题分享与浅析
  15. codeforces1467E Distinctive Roots in a Tree
  16. 实现Ubuntu网络快速连接
  17. Java日期——获取今天是星期几
  18. 想快速发表自然语言处理论文?推荐一个出论文的好方向!
  19. Google首席决策师告诉你AI和数据科学团队需要哪10种角色?
  20. 立创EDA仿真入门1 基本操作

热门文章

  1. SHELL简单脚本编写
  2. 在vue.js中省市选择
  3. Oracle快速克隆安装
  4. iOS面试题总结 二
  5. 【Ubuntn】Ubuntu随笔
  6. AJAX技术其实就是多年前我就使用过的XMLHTTP
  7. YARN的job提交过程
  8. Spark2.0研究
  9. JDBC与Druid简单介绍及Druid与MyBatis连接数据库
  10. Hibernate 查询数据库中的数据