【C++初阶】反向迭代器的实现

👦个人主页:@Weraphael

✍🏻作者简介:目前学习C++和算法

✈️专栏:C++航路

🐋 希望大家多多支持,咱一起进步!😁

如果文章对你有帮助的话

欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


目录

一、什么是迭代器

若要访问容器里的元素,最常见的方式可以通过迭代器。迭代器是一个变量,相当于容器和算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。因此,迭代器可以认为是指针,但不一定就是指针。

特别注意:容器stackqueuepriority_queue是不支持迭代器的

常见的迭代器有正向迭代器和反向迭代器

【正向迭代器】

正向迭代器++是往后遍历,因此遍历的顺序为1 2 3 4

【代码实现】

cpp 复制代码
#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main()
{
	vector<int> v{ 1, 2,3, 4 };
	vector<int>::iterator vit = v.begin();
	while (vit != v.end())
	{
		cout << *vit << ' ';
		vit++;
	}
	cout << endl;
	return 0;
}

【输出结果 】

【反向迭代器】

对比正向迭代器,反向迭代器++是往前遍历的,因此遍历的顺序为4 3 2 1

【代码实现】

cpp 复制代码
#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main()
{
	vector<int> v{ 1, 2,3, 4 };
	vector<int>::reverse_iterator vrit = v.rbegin();
	while (vrit != v.rend())
	{
		cout << *vrit << ' ';
		vrit++;
	}
	cout << endl;

	return 0;
}

【输出结果】

二、如何模拟实现反向迭代器

我们发现,对比正向迭代器和反向迭代器,只有前后置++/--是有所差别的。因此,对于list可以将原来的正向迭代器给拷贝一份,然后将++运算符重载中修改为指向前一个结点,---运算符重载修改为指向后一个结点。对于vector可以是类似于实现list正向迭代器一样,封装一个类,,然后运算符重载去处理。

可是以上这样实现就有点麻烦,我们可以看看库是如何实现的

从上我们可以发现,在库里面其实使用的是适配器来实现反向迭代器 的,对正向迭代器进行了封装。用正向迭代器的++实现返向迭代器的++,用正向迭代器的--来实现反向迭代器的--

接下来再来看看库里是如何实现reverse_iterator

以上接口唯独最奇怪的是解引用,它解引用的结果是当前位置的前一个对象(*--tmp),但是再回过头重新看rbeginrend就会明白(上上图)

每次解引用都会先得到rbegin前一个位置的数据,直到rbegin == rend遍历结束,这里就体现了一个镜像对称特性,认为反向迭代器与正向迭代器是具有对称关系的

三、代码实现

cpp 复制代码
#pragma once
namespace wj
{
	template<class Iterator, class Ref, class Ptr>
	struct ReverseIterator
	{
		Iterator _it;
		typedef ReverseIterator<Iterator, Ref, Ptr> Self;

		// 正向迭代器构造反向迭代器
		ReverseIterator(Iterator it)
			:_it(it)
		{}

		Ref operator*()
		{
			// --有副作用,可以拷贝一个副本tmp操作
			Iterator tmp = _it;
			return *--tmp;
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		Self& operator++() // 前置
		{
			--_it;
			return *this;
		}

		Self operator++(int) // 后置
		{
			Iterator tmp(_it);
			_it--;
			return tmp;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}

		Self& operator--(int)
		{
			Iterator tmp(_it);
			_it++;
			return tmp;;
		}

		bool operator!=(const Self& s) const
		{
			return _it != s._it;
		}

		bool operator==(const Self& s) const
		{
			return _it == s._it;
		}
	};
}
相关推荐
Mr_Tony1 分钟前
Swift 中的 Combine 框架完整指南(含示例代码 + 实战)
开发语言·swift
无心水4 分钟前
22、Java开发避坑指南:日期时间、Spring核心与接口设计的最佳实践
java·开发语言·后端·python·spring·java.time·java时间处理
婷婷_1727 分钟前
DWC Ethernet QoS VLAN高级功能深度解析
网络·学习·程序人生·ethernet·芯片·vlan·gmac
Hello.Reader9 分钟前
双卡 A100 + Ollama 最终落地手册一键部署脚本、配置文件、预热脚本与 Python 客户端完整打包
开发语言·网络·python
cch891817 分钟前
汇编VS C++:底层控制与高效开发之争
java·开发语言
计算机安禾21 分钟前
【数据结构与算法】第30篇:哈希表(Hash Table)
数据结构·学习·算法·哈希算法·散列表·visual studio
AIminminHu22 分钟前
OpenGL渲染与几何内核那点事-项目实践理论补充(三-1-(3):番外篇-当你的CAD打开“怪兽级”STL时:从内存爆炸到零拷贝的极致优化
c++·零拷贝·mmap·内存拷贝
水饺编程22 分钟前
第4章,[标签 Win32] :SysMets3 程序讲解04,垂直滚屏重绘
c语言·c++·windows·visual studio
xiaoye-duck22 分钟前
《算法题讲解指南:动态规划算法--子序列问题(附总结)》--32.最长的斐波那契子序列的长度,33.最长等差数列,34.等差数列划分II-子序列
c++·算法·动态规划
lifewange27 分钟前
代码托管平台
开发语言