本节我们将进入迭代器适配器的学习。迭代器适配器,顾名思义,就是自定义迭代器,在原有迭代器的基础上进行接口的约束或升级。如果读者还不知道什么是适配器的话,可自行跳转《C++ STL容器适配器简介》深入学习。对于SLT库中的所有容器,我们总共有5种迭代器,分别是前向迭代器、双向迭代器、随机访问迭代器、输入迭代器和输出迭代器。我们通常使用迭代器来进行容器的遍历和快速访问首尾元素,这里演示一下通过迭代器遍历map容器:
#include<iostream> #include<map> #include<string> using namespace std; /*通过迭代器遍历map容器*/ void test() { map<string,string> mp{ {"Dotcpp","dotcpp.com"}, {"C语言教程","https://www.dotcpp.com/course/c/"}, {"计算机二级C语言","https://www.dotcpp.com/course/erjic/"}, {"数据结构教程","https://www.dotcpp.com/course/ds/"}, {"Linux命令","https://www.dotcpp.com/course/linuxcmd/"} };//初始化列表 cout << "Dotcpp还有很多教程:\n"; for(map<string,string>::iterator it = mp.begin();it!=mp.end();++it) { cout <<"想要学习【" << it->first << "】可以访问【" <<it->second << "】\n"; } } int main() { test(); return 0; }
编译结果如下:
STL提供了4大类迭代器适配器,分别是:
反向迭代器 | reverse_iterator | 反向遍历容器元素 | 逆序处理数据 |
rbegin() , rend() | 返回反向迭代器的便捷函数 | 容器逆序遍历 | |
crbegin() , crend() | 返回常量反向迭代器 | 常量逆序遍历 | |
插入迭代器 | back_insert_iterator | 在容器末尾插入元素 | 向后构建集合 |
back_inserter() | 创建back_insert_iterator的便捷函数 | 算法输出到容器末尾 | |
front_insert_iterator | 在容器头部插入元素 | 向前构建集合 | |
front_inserter() | 创建front_insert_iterator的便捷函数 | 算法输出到容器头部 | |
insert_iterator | 在指定位置插入元素 | 任意位置插入 | |
inserter() | 创建insert_iterator的便捷函数 | 指定位置插入数据 | |
流迭代器 | istream_iterator | 从输入流读取数据 | 文件/控制台输入处理 |
ostream_iterator | 向输出流写入数据 | 格式化数据输出 | |
istreambuf_iterator | 从流缓冲区读取字符 | 底层流操作 | |
ostreambuf_iterator | 向流缓冲区写入字符 | 底层流输出 | |
移动迭代器 | move_iterator | 移动语义的迭代器 | 高效资源转移 |
make_move_iterator() | 创建move_iterator的工厂函数 | 容器间资源移动 |
表格对迭代器适配器进行了具体的描述,笔者这里就不过多赘述了,就刚才我们遍历的map容器举个例子,我们通过reverse_iterator来构造迭代器适配器进行逆序遍历:
#include<iostream> #include<map> #include<string> using namespace std; /*通过迭代器适配器——reverse_iterator逆序遍历map容器*/ void test() { map<string,string> mp{ {"Dotcpp","dotcpp.com"}, {"C语言教程","https://www.dotcpp.com/course/c/"}, {"计算机二级C语言","https://www.dotcpp.com/course/erjic/"}, {"数据结构教程","https://www.dotcpp.com/course/ds/"}, {"Linux命令","https://www.dotcpp.com/course/linuxcmd/"} };//初始化列表 cout << "Dotcpp还有很多教程:\n"; /*开始构造迭代器适配器*/ map<string,string>::reverse_iterator nbegin(mp.end()); map<string,string>::reverse_iterator nend(mp.begin()); for(;nbegin!=nend;++nbegin) { cout <<"想要学习【" << nbegin->first << "】可以访问【" <<nbegin->second << "】\n"; } } int main() { test(); return 0; }
代码编译如下:
我们通过reverse_iterator来构造迭代器适配器,成功实现++而非--的操作反向遍历了map容器!
总结:通过迭代器适配器,我们就能在基础迭代器上扩展或约束创建新的迭代器,以满足个性化需求。值得一提的是,迭代器适配器主要应用于桥接算法、减少样板代码和兼容不同接口上。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程