加入收藏 | 设为首页 | 会员中心 | 我要投稿 银川站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

什么是C++ STL迭代器适配器

发布时间:2023-04-25 10:55:39 所属栏目:语言 来源:
导读:通过学习 C++ STL 标准库中的容器我们知道,无论是序列式容器还是关联式容器(包括哈希容器),要想遍历容器中存储的数据,就只能用使用该容器模板类中提供的迭代器。《C++ STL迭代器》一节提到,C++ STL 标准库中迭

通过学习 C++ STL 标准库中的容器我们知道,无论是序列式容器还是关联式容器(包括哈希容器),要想遍历容器中存储的数据,就只能用使用该容器模板类中提供的迭代器。

《C++ STL迭代器》一节提到,C++ STL 标准库中迭代器大致分为 5 种类型,分别是输入迭代器、输出迭代器、前向迭代器、双向迭代器以及随机访问迭代器。值得一提的是,这 5 种迭代器是 STL 标准库提供的最基础的迭代器,很多场景中遍历容器的需求,它们并不适合。

举个例子,假设有一个 list 容器,现在需要逆序输出该容器中存储的所有元素。要知道,list 容器模板类提供的是双向迭代器,如果使用该类型迭代器实现逆序操作,实现代码如下:

#include <iostream>

#include <list>

using namespace std;

int main()

{

std::list<int> values{1,2,3,4,5};

//找到遍历的开头位置和结尾位置

std::list<int>::iterator begin = --values.end();

std::list<int>::iterator end = --values.begin();

//开始遍历

while (begin != end)

{

cout << *begin << " ";

--begin;

}

return 0;

}

程序执行结果为:

5 4 3 2 1

相比上面这种实现思路,C++ STL 标准库中还提供有更简单的方法,就是使用迭代器适配器。

关于适配器,在讲解容器适配器时就已经做过详细的讲解,这里不再做过多赘述,读者可阅读《C++ STL容器适配器》一节做详细了解。

所谓迭代器适配器,其本质也是一个模板类,比较特殊的是,该模板类是借助以上 5 种基础迭代器实现的。换句话说,迭代器适配器模板类的内部实现,是通过对以上 5 种基础迭代器拥有的成员方法进行整合、修改,甚至为了实现某些功能还会添加一些新的成员方法。由此,将基础迭代器“改头换面”,就变成了本节要讲的迭代器适配器。

本质上讲,迭代器适配器仍属于迭代器,可以理解为是基础迭代器的“翻新版”或者“升级版”。同时,“xxx 迭代器适配器”通常直接称为“xxx 迭代器”。

C++ STL迭代器适配器种类

C++ STL迭代器适配器种类名称功能反向迭代器(reverse_iterator)又称“逆向迭代器”,其内部重新定义了递增运算符(++)和递减运算符(--),专门用来实现对容器的逆序遍历。安插型迭代器(inserter或者insert_iterator)通常用于在容器的任何位置添加新的元素,需要注意的是,此类迭代器不能被运用到元素个数固定的容器(比如 array)上。流迭代器(istream_iterator / ostream_iterator)

流缓冲区迭代器(istreambuf_iterator / ostreambuf_iterator)输入流迭代器用于从文件或者键盘读取数据;相反,输出流迭代器用于将数据输出到文件或者屏幕上。

输入流缓冲区迭代器用于从输入缓冲区中逐个读取数据;输出流缓冲区迭代器用于将数据逐个写入输出流缓冲区。移动迭代器(move_iterator)此类型迭代器是 C++ 11 标准中新添加的,可以将某个范围的类对象移动到目标范围,而不需要通过拷贝去移动。

以上 4 种迭代器的用法,后续章节会做详细介绍。

实际上,前面在学习各种容器的迭代器时,我们经常会使用到反向迭代器。下面样例,演示了用反向迭代器适配器遍历 list 容器的实现过程:

#include <iostream>

#include <list>

using namespace std;

int main()

{

std::list<int> values{ 1,2,3,4,5 };

//找到遍历的起点和终点,这里无需纠结定义反向迭代器的语法,后续会详细讲解

std::reverse_iterator<std::list<int>::iterator> begin = values.rbegin();

std::reverse_iterator<std::list<int>::iterator> end = values.rend();

while (begin != end) {

cout << *begin << " ";

//注意,这里是 ++,因为反向迭代器内部互换了 ++ 和 -- 的含义

++begin;

}

return 0;

}

程序执行结果为:

5 4 3 2 1

可以看到,程序中通过调用 list 容器模板类提供的 rbegin() 和 rend(),就可以获得逆序遍历容器所需要的反向迭代器,从而轻松实现逆序输出容器中存储的所有数据。

(编辑:银川站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!