【C++】反向迭代器精讲(以lIst为例)

news2024/11/27 9:55:40

目录

二,全部代码

三,设计思路 

1. 讨论

2. 关于迭代器文档一个小细节 

结语


 

一,前言

如果有小伙伴还未学习普通迭代器,请参考这篇文章中的普通迭代器实现。

【STL】list用法&试做_底层实现_花果山~~程序猿的博客-CSDN博客

 参考list源码,这里直接说结果,发现源码通过借用普通迭代器来构造反向迭代器。

二,全部代码

namespace my_list
{
	template <class T>
	struct list_node
	{
		list_node(const T& data = T())
			: _data(data)
			, _next(nullptr)
			, _prv(nullptr)
		{}

		T _data;
		list_node* _next;
		list_node* _prv;
	};

	template <class T, class Ref, class Ptr>
	struct list_iterator
	{
		typedef list_node<T> Node;
		typedef list_iterator< T, Ref, Ptr> iterator;

		Node* _node;

		list_iterator(Node* node)
			: _node(node)
		{}

		bool operator!= (const iterator& it)
		{
			return _node != it._node;
		}

		bool operator==(const iterator& it)
		{
			return _node == it._node;
		}

		iterator& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		iterator& operator--()
		{
			_node = _node->_prv;
			return *this;
		}

		iterator operator++(int)
		{
			iterator tmp(*this);
			_node = _node->_next;
			return *tmp;
		}

		Ptr operator*()
		{
			return _node->_data;

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

	template <class Iterator, class Ref, class Ptr>
	struct _reverse_iterator
	{
		typedef _reverse_iterator<Iterator, Ref, Ptr>  reverse_iterator;

		Iterator _cur;
		
		_reverse_iterator(const Iterator& cur)
			: _cur(cur)
		{}

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

		reverse_iterator operator++(int)
		{
			reverse_iterator temp(*this);
			--_cur;
			return temp;
		}

		reverse_iterator& operator--()
		{
			++_cur;
			return _cur;
		}

		reverse_iterator operator--(int)
		{
			reverse_iterator temp(*this);
			++_cur;
			return temp;
		}

		// != 
		bool operator!=(const reverse_iterator& end)
		{
			return _cur != end._cur;
		}

		bool operator==(const reverse_iterator&  end)
		{
			return _cur == end._cur;
		}

		// *     
		Ptr operator*() 
		{
			auto tmp = _cur;
			--tmp;
			return *tmp;
		}

		// ->
		Ref operator->()
		{
			return &(operator*());
		}
	};

	template <class T>
	class list
	{
		typedef list_node<T> Node;
	public:
		typedef list_iterator<T, T*, T&>  iterator;
		typedef list_iterator<T, const T*, const T&> const_iterator;

		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());
		}

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

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

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


		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		const_iterator begin() const
		{
			return const_iterator(_head->_next);
		}

		const_iterator end() const
		{
			return const_iterator(_head);
		}
..... //list其他成员函数这里就不再赘述了

三,设计思路 

设计思路比较简单,本质上是复用普通迭代器的函数,其他重载函数思想跟普通函数差不多。

但这里也有一个比较艺术性的设计:

1. 讨论

那这里我们来讨论一下,这个反向迭代器是否能给vector使用??  答案是肯定的

看图:

结论:反向迭代器:迭代器的适配器。

2. 关于迭代器文档一个小细节 

那是不是所有的容器都合适呢? 

不一定,因为容器的普通迭代器最起码要支持++,--接口(比如:foward_list就不支持--,所以其没有反向迭代器)

这里补充一些关于[STL]文档的使用,从迭代器功能角度分为三类:

1. forward_iterator  (单向迭代器)      支持——>  ++                比如: foward_list等等

2. bidirectional_iterator(双向迭代器)   ——>  ++  --            比如: list等

3. radom_access_iterator  (随机迭起器) ——>  ++ --  + -   比如:vector, deque等, 第三中迭代器继承1,2种

那意义又是什么??

意义:就是提示在使用迭代器时,接口会提示你合适的的迭代器类型。

 

结语

   本小节就到这里了,感谢小伙伴的浏览,如果有什么建议,欢迎在评论区评论,如果给小伙伴带来一些收获请留下你的小赞,你的点赞和关注将会成为博主创作的动力

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

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

相关文章

Android架构 架构和 CPU ABI - NDK

查看设备架构 adb -s emulator-5554 shell getprop ro.product.cpu.abi C:\Users\liyd>adb -s emulator-5554 shell getprop ro.product.cpu.abi x86_64C:\Users\liyd>adb -s 804c11f1 shell getprop ro.product.cpu.abi arm64-v8amumu模拟器12 C:\Users\liyd>adb …

MobaXterm 突破14个session限制

通常情况下&#xff1a;随着工作时间的增长&#xff0c;我们会保存许许多多的linux到本地的mobastream&#xff0c;然后当超过14个&#xff0c;就会被被限制&#xff0c;这个会让人很头疼。 1. 安装python&#xff0c;配置好环境变量 测试安装成功&#xff1a; 2. 基于项目进行…

uniapp点击事件在小程序中无法传参

这个问题很是神奇&#xff0c;第一次遇到。在h5中&#xff0c;点击事件可以正常传参&#xff0c;打包小程序后确失效了。 修改&#xff1a;for循环中的key&#xff0c;使用 index就好了

视频汇聚/视频云存储/视频监控管理平台EasyCVR启动时打印starting server:listen tcp,该如何解决?

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;可实现视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、H.265自动转码H.264、平台级联等。为了便于用户二次开发、调用与集成&#xff0c;…

SpringBoot集成redis-Jedis

文章目录 1.相关概念2.环境搭建及测试 1.相关概念 Springboot学习笔记&#xff1a;https://blog.csdn.net/meini32/article/details/132544107 Redis快速入门&#xff1a;https://blog.csdn.net/meini32/article/details/132666283 2.环境搭建及测试 redis相关配置 Sprin…

车载域控制器DCU浪涌防护推荐TVS二极管

为了解决分布式EEA的这些问题&#xff0c;汽车工程师开始逐渐把很多功能相似、分离的ECU功能集成整合到一个比ECU性能更强的处理器硬件平台上&#xff0c;这就是汽车“域控制器&#xff08;Domain Controller Unit&#xff0c;DCU&#xff09;”。车载域控制器DCU大大优化整车的…

【Flink】关于jvm元空间溢出,mysql binlog冲突的问题解决

问题一&#xff1a;7张表是同一个mysql中的&#xff0c;我们进行增量同步时分别用不同的flink任务读取&#xff0c;造成mysql server-id冲突问题&#xff0c;如下&#xff1a; Caused by: io.debezium.DebeziumException: A slave with the same server_uuid/server_id as this…

LINUX内核启动流程-1

1、BIOS启动 硬件设置从OXFFFF0启动:CPU硬件设置加电即进入16位实模式状态运行,CPU硬件逻辑设计为加电瞬间强行将CS的值置为oxF000,IP的值置为0xFFF0,这样CS:IP就指向0xFFFF0这个地址位置。 BIOS程序的入口地址恰恰就是0xFFFF0 ! 也就是说,BIOS程序的第一条指令就设计在…

【0220】stats collector如何得知pgStatSock中的消息类型、消息报文内容以及消息是否完整?

1. vacuum、writer、checkpointer等进程如何发送统计信息给stats collector 前面已经图文并茂的讲解过,stats collector进程通过UDP方式与其他进程进行通信,在初始化资源时,通过socket()系统函数得到一个全局套接字fd。后续其他进程有统计消息时,通过该句柄,可发送消息给…

sql-gen:点击生成SQL、RO、VO的工具

sql-gen仓库地址&#xff1a;码云 Github 1. 概述 sql-gen是一个用于提高后端接口开发效率的小工具&#xff0c;主要有如下功能&#xff1a; 生成连表SQL语句根据WHERE条件来生成封装查询条件的实体类&#xff08;RO&#xff09;根据SELECT列来生成封装查询结果的实体类&…

学习笔记|小数点控制原理|数码管动态显示|段码跟位码|STC32G单片机视频开发教程(冲哥)|第十集:数码管动态显示

文章目录 1.数码管动态刷新的原理2.动态刷新原理3.8位数码管同时点亮新建一个数组选择每个位需要显示的内容实战小练&#xff1a;简易10秒免单计数器将刷新动作写成函数 课后练习: 1.数码管动态刷新的原理 上述图片引用自&#xff1a;51单片机初学2-数码管动态扫描 用一排端口来…

追求数学之美

菲尔兹奖得主玛丽安米尔札哈尼说过&#xff1a;“只有在那些最有耐心的信徒面前&#xff0c;数学才会展现出它美丽的一面。”她的意思是&#xff0c;数学之美的绽放通常需要一定的时间。有时你需要费上一番功夫才能欣赏到建筑的美。数学的美也是这样&#xff0c;只要你拥有足够…

FHE 嵌合 MHE

参考文献&#xff1a; [NW96] Nisan N, Wigderson A. Lower bounds on arithmetic circuits via partial derivatives[J]. Computational complexity, 1996, 6: 217-234. Cites “M. Ben-Or, Private communication”.[Gen09] Gentry C. A fully homomorphic encryption schem…

基于32位单片机的感应灯解决方案

感应灯是一种常见照明灯&#xff0c;提起感应灯&#xff0c;相信大家并不陌生&#xff0c; 它在一些公共场所、卫生间或者走廊等场所&#xff0c;使用的较为广泛&#xff0c;同时它使用起来也较为方便省电。“人来灯亮&#xff0c;人走灯灭”的特性&#xff0c;使他们在部分场景…

利用Python和pandas分析瑞幸和茅台联名咖啡的市场策略

金融数据分析在投资决策和市场制定策略中发挥了至关重要的作用&#xff0c;而品牌价值分析是市场营销中的一个环节&#xff0c;它可以帮助企业了解其品牌在市场中的地位和价值&#xff0c;刚好最近瑞幸和茅台联名咖啡是近期备受关注的合作咖啡项目&#xff0c;其联名咖啡产品在…

安防监控/视频存储/视频汇聚平台EasyCVR如何接入智能分析网关V4?

TSINGSEE青犀AI边缘计算网关硬件 —— 智能分析网关目前有5个版本&#xff1a;V1、V2、V3、V4、V5&#xff0c;每个版本都能实现对监控视频的智能识别和分析&#xff0c;支持抓拍、记录、告警等&#xff0c;每个版本在算法模型及性能配置上略有不同。硬件可实现的AI检测包括&am…

c++中的对齐问题

c中的对齐问题 需要对齐的原因 尽管内存是以字节为单位&#xff0c;但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存&#xff0c;我们将上述这些存取单位称为内存存取粒度. 现在考虑4字节存取粒度的处理器取in…

java八股文面试[JVM]——引用计数、可达性分析

要想进行垃圾回收&#xff0c;得先知道什么样的对象是垃圾。 引用计数法 对于某个对象而言&#xff0c;只要应用程序中持有该对象的引用&#xff0c;就说明该对象不是垃圾&#xff0c;如果一个对象没有任何指针对其引用&#xff0c;它就是垃圾。 引用计数法在对象头处维护一…

论坛系统公共组件部分

1.在Java⽬录下创建包&#xff0c;在Resources⽬录下创建⽂件夹&#xff0c;结构如下 ├─java # java⽂件区 │ └─com │ └─example │ └─demo │ ├─common # 公共类 │ ├─config # 配置…

DBeaver新建Elasticsearch连接报错Error downloading driver libraries解决方案

1.软件版本背景 DBeaver Ultimate 22.1.0 elasticsearch 7.10 可能因DBeaver的版本不同&#xff0c;导致页面略有差异&#xff0c;请自行脑补&#xff01; 2.新建数据库&#xff08;Elasticsearch&#xff09;连接 点击新建数据库连接按钮 选择Elasticsearch 填写相关配置…