C++【STL】之反向迭代器

news2024/11/17 7:21:20

反向迭代器

前面在vector和list的模拟实现中都有讲到正向迭代器,今天我们就来讲解一下反向迭代器的思想和模拟实现,在某些场景下还是很实用的,下面正文直接开始。

文章目录:

  • 反向迭代器
    • 1. 反向迭代器结构
    • 2. 反向迭代器实现
      • 2.1 多参数模板
      • 2.2 对称思想
      • 2.3 完整代码
    • 3. 反向迭代器vector应用
    • 4. 反向迭代器list引用

1. 反向迭代器结构

反向迭代器reverse_iterator用于反向遍历容器,它也是由一个类来封装的

template<class Iterator>
struct __reverse_iterator
{
	Iterator _cur;	//正向迭代器类做成员变量
	__reverse_iterator(Iterator cur) //构造正向迭代器
		:_cur(cur)
	{}
    //...
};

STL库中反向迭代器的设计讲究完美的对称性,rbegin() 指向最后一个有效元素的下一个位置,rend() 指向第一个有效元素,与正向迭代器的指针位置刚好相反

拿vector对象举个例子

Self& operator++()
{
    --_cur; //正反迭代器,++,--反向操作
    return *this;
}

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

2. 反向迭代器实现

反向迭代器的实现主要还是依于对正向迭代器的复用,外加了一点小细节思想,这里我们实现的依旧是简易版本

2.1 多参数模板

前面在模拟实现list时,运用了多参数模板来解决const对象代码冗余问题,在反向迭代器的实现中也运用了相同原理,通过对形参传递不同的对象,变换为不同的迭代器

template<class Iterator, class Ref, class Ptr>
struct __reverse_iterator
{
	//...
};

其中Ref表示引用对象,Ptr表示指针对象

2.2 对称思想

STL大佬在设计反向迭代器时,为了追求与正向迭代器的对称,将首尾指针得到指向反向保持一致,如上图,即rbegin()end()位置,rend()begin()位置

在这样的设计下,rbegin()rend()的实现就可以直接对应复用了,而operator*()返回的就不是当前所指向的对象,而是成了上一个对象

reverse_iterator rbegin() 
{ 
	reverse_iterator(end()); 
}

reverse_iterator rend() 
{ 
	reverse_iterator(begin()); 
}

operator*()

Ref operator*()
{
	Iterator tmp = _cur;
	return *--tmp;	//返回上一个对象
}

2.3 完整代码

至于其他的实现都是复用的正向迭代器,比较简单,这里直接上完整代码,相信大佬,们一看就能明白

#pragma once
namespace Sakura
{
	template<class Iterator, class Ref, class Ptr>
	struct __reverse_iterator
	{
		typedef __reverse_iterator<Iterator, Ref, Ptr> self; //重命名
		Iterator _cur; //正向迭代器类做成员变量

		__reverse_iterator(Iterator cur) //构造正向迭代器
			:_cur(cur)
		{}

		Ref operator*()
		{
			Iterator tmp = _cur;
			return *--tmp;
		}

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

		self& operator++()
		{
			--_cur;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			--_cur;
			return tmp;
		}

		self& operator--()
		{
			++_cur;
			return *this;
		}

		self operator--(int)
		{
			self tmp(*this);
			++_cur;
			return tmp;
		}

		bool operator!=(const self& s)
		{
			return (_cur != s._cur);
		}

		bool operator==(const self& s)
		{
			return (_cur == s._cur);
		}
	};
}

3. 反向迭代器vector应用

vector 类中,定义出反向迭代器所需的函数即可

template<class T>
class vector
{
public:
	//反向迭代器
	typedef _reverse_iterator<iterator, T&, T*> reverse_iterator;
	typedef _reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;

	reverse_iterator rbegin()
	{
		return reverse_iterator(end());
	}

	reverse_iterator rend()
	{
		return reverse_iterator(begin());
	}

	const_reverse_iterator rbegin() const
	{
		return const_reverse_iterator(end());
	}

	const_reverse_iterator rend() const
	{
		return const_reverse_iterator(begin());
	}
	//...
};

4. 反向迭代器list引用

list 类中,定义出反向迭代器所需的函数即可

template<class T>
class list
{
public:
	//反向迭代器
	typedef __reverse_iterator<iterator, T&, T*> reverse_iterator;
	typedef __reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;

	reverse_iterator rbegin() 
	{ 
		return reverse_iterator(end()); 
	}

	reverse_iterator rend() {
		return reverse_iterator(begin()); 
	}

	const_reverse_iterator rbegin() const 
	{
		return const_reverse_iterator(end());
	}

	const_reverse_iterator rend() const 
	{ 
		return const_reverse_iterator(begin()); 
	}
	//...
};

C++【STL】之反向迭代器,到这里就介绍结束了,本篇文章对你由帮助的话,期待大佬们的三连,你们的支持是我最大的动力!

文章有写的不足或是错误的地方,欢迎评论或私信指出,我会在第一时间改正!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/676528.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一起学AI:核心基础概念

一起学AI&#xff1a;核心基础概念 AI基础概念什么是学习率&#xff1f;batchsize和epoch分别是什么&#xff1f;梯度消失与梯度爆炸是什么&#xff1f;什么是过拟合、欠拟合和泛化&#xff1f;归一化、正则化、标准化是什么&#xff1f;线性回归和逻辑回归是什么&#xff1f;神…

端午特别征文

前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 韩顺平教育的java坦克大战 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、Java绘图技术 1.g.drawOval()是什么&#xff1f; 画椭圆函数g.drawOval(); (宽高时候为圆形) …

Kafka系列之:一次性传送和事务消息传递

Kafka系列之&#xff1a;一次性传送和事务消息传递 一、目标二、关于事务和流的一些知识三、公共接口四、示例应用程序五、新配置六、计划变更1.幂等生产者保证2.事务保证 七、关键概念八、数据流九、授权十、RPC 协议总结1.获取请求/响应2.生产请求/响应3.ListOffset请求/响应…

GIT —— 基本操作,分支管理,远程操作

GIT 企业开发 最近找实习&#xff0c;在完善简历&#xff0c;遂发一发存货&#xff0c;有待持续完善&#xff0c;我认为这部分非常的有意义 1. 基本操作 1.1 创建&#xff0c;配置本地仓库 创建 mkdir gitcode cd gitcode git init配置 git config user.name "bts&quo…

HTTP 超文本传输协议

1.HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09; 是一种用于传输超媒体文档&#xff08;例如HTML文件&#xff0c;可以包含文本&#xff0c;视频&#xff0c;图片&#xff0c;音乐&#xff0c;地图定位&#xff09;的应用层协议&#x…

【windows10】查看计算机的WIFI密码

【windows10】查看计算机的WIFI密码 1、背景2、操作 1、背景 无线路由器设置完密码后&#xff0c;经常会忘记。 当有新的设备需要接入网络的时候&#xff0c;如何能快速获得wifi密码呢&#xff1f; 本博客分享一种通过已联网的计算机来查看wifi密码。 2、操作 -step-2.1、打…

阿里云服务器的备案流程和规定如何?如何办理备案手续?

阿里云服务器的备案流程和规定如何&#xff1f;如何办理备案手续&#xff1f;   一、备案流程概述   阿里云服务器的备案流程分为五个主要步骤&#xff1a;1&#xff09;实名认证&#xff1b;2&#xff09;填写备案信息&#xff1b;3&#xff09;上传资料&#xff1b;4&…

Web服务器群集:链路聚合与桥接

目录 一、理论 1.链路聚合 2.bond模式 3.team模式 4.bond和team区别 二、实验 1.实现bond网络接口 2.实现team网络接口 三、总结 一、理论 1.链路聚合 &#xff08;1&#xff09;概念 链路聚合&#xff08;Link Aggregation&#xff09;&#xff0c;它是一个计算机…

【Vue】Vite基础学习

文章目录 Vite 基础学习一、单页面应用程序二、Vite 基本使用2.1 创建 vite 项目2.2 项目结构2.3 项目运行流程 Vite 基础学习 一、单页面应用程序 单页面应用程序&#xff08;英文名&#xff1a;Single Page Application&#xff09;简称 SPA&#xff0c;顾名思义&#xff0c…

springboot:定时任务

目录 一、实现定时任务的方法一&#xff1a;基于JDK 方法一&#xff1a;使用JDK自带的Timer类 法二&#xff1a;使用ScheduleExecutorsService类 二、基于Spring Task实现定时任务(推荐使用) 三、基于Quartz实现定时调度 四、使用分布式定时任务框架&#xff1a;elastic-j…

基础-进阶-升级~图解SpringSecurity的RememberMe流程|源码

前言 今天我们来聊一下登陆页面中“记住我”这个看似简单实则复杂的小功能。 如图就是博客园登陆时的“记住我”选项&#xff0c;在实际开发登陆接口以前&#xff0c;我一直认为这个“记住我”就是把我的用户名和密码保存到浏览器的 cookie 中&#xff0c;当下次登陆时浏览器…

关于Synchronized的小结

目录 一.特性 1.既是乐观锁又是悲观锁 2.是轻量级锁,也是重量级锁 3.不是读写锁,是互斥锁 4.是可重入锁 5.非公平锁 6.加锁之后,运行完毕自动解锁释放资源 二:Synchronized使用 第一种:定义一个额外的变量来控制加锁和解锁(类似于吉祥物) 第一种:直接给类/方法上锁 三…

【Linux】MySQL备份与恢复

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 MySQL备份与恢复 一、数据备份的重要性1.数据库备份的分类2.常见的备份方法3.MySQL完全备份与分类 二、MySQL 日志管理三、MySQL 备份与恢复1.MySQL 完全备份1.物理冷备份与恢…

Linux 服务器以及各个系统下安装

Linux 服务器 Linux是操作系统&#xff1a; Linux作为自由软件和开放源代码软件发展中最著名的例子&#xff0c;背靠社区与商业化的使用&#xff0c;使其得到了广泛的应用与发展。 Linux无处不在&#xff1a; 世界上500个最快的超级计算机90&#xff05;以上运行Linux发行版…

【MyBatis学习】动态SQL的使用,MyBatis还能这样使用?惊掉了我的下巴 ,赶快带着好奇心一起畅游动态SQL的海洋吧! ! !

前言: 大家好,我是良辰丫,今天我们来学习一下MyBatis中动态sql的使用,带着疑惑走进我们今天的学习! ! !&#x1f48c;&#x1f48c;&#x1f48c; &#x1f9d1;个人主页&#xff1a;良辰针不戳 &#x1f4d6;所属专栏&#xff1a;javaEE进阶篇之框架学习 &#x1f34e;励志语句…

短视频矩阵源码开发部署技术解析

短视频矩阵源码开发涉及到多个方面的技术&#xff0c;包括但不限于以下几点&#xff1a; 抖yinAPI&#xff1a;需要通过API获取抖音的视频、用户、评论、点赞等数据。 抖yinSDK&#xff1a;如果需要开发一些原生的功能&#xff0c;比如分享、登录、支付等&#xff0c;需要使用…

深入解析大型语言模型:从训练到部署大模型

简介 随着数据科学领域的深入发展&#xff0c;大型语言模型—这种能够处理和生成复杂自然语言的精密人工智能系统—逐渐引发了更大的关注。 LLMs是自然语言处理&#xff08;NLP&#xff09;中最令人瞩目的突破之一。这些模型有潜力彻底改变从客服到科学研究等各种行业&#x…

【每天40分钟,我们一起用50天刷完 (剑指Offer)】第四天 4/50

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

Jenkins集成Sonar与Gitlab代码质量检测

前提默认 安装docker19&#xff0c;与docker-compose 安装Jenkins 1、docker-compose.yaml配置 version: 3 services: jenkins: #network_mode: "host" #镜像 image: jenkins/jenkins:2.399-jdk11 #容器名称 container_name: jenkins #启动模式 res…

探索uniapp+vue3解析markdown语法|uniapp键盘撑起

最近正在尝试使用uniappvue3开发仿制chatgpt会话功能。 如上图&#xff1a;经过测试在h5/App端/小程序端 均支持markdown语法解析&#xff0c;键盘撑起后&#xff0c;整体页面和顶部自定义导航栏不会被顶起。 uniapp markdown解析及语法高亮 使用了markdown-it和highlight.js…