C++ 如何快速实现一个容器的迭代器

news2024/12/22 9:48:05

100编程书屋_孔夫子旧书网

引言

C++的标准库中的容器都会提供迭代器,如果一个容器满足forward_range,那么这个容器一般会提供以下成员类型和函数:

  • iterator
  • const_iterator
  • begin
  • end
  • begin
  • cend

如果该容器还满足bidirectional_range,那么该容器还会额外提供以下成员类型和函数:

  • reversed_iterator
  • const_reversed_iterator
  • rbegin
  • rend
  • rcbegin
  • rcend

笔者曾经在网上搜索过如何实现C++迭代器的文章,但是大多数文章都只是实现了一个最普通的迭代器,从学习原理的角度来说是非常好的,但是相比于标准库或者其他工业化的库来说可能是非常不完整的,所以笔者打算在本文中尽可能将容器中的迭代器部分完整地实现出来。

大多数人可能由于种种原因,C++的标准还停留在C++11,所以我们这里分别使用C++11和最新的标准来编写迭代器。


什么是迭代器

我们这里引用cppreference原话:

Iterators are a generalization of pointers that allow a C++ program to work with different data structures (for example, containers and ranges (since C++20)) in a uniform manner.

从定义不难看出,迭代器是一个泛化的指针。


指针

既然迭代器是泛化的指针,那么我们可以通过指针来了解迭代器。我们知道指针共有两个位置可以添加const关键字,共有4种可能,我们将他们对应到迭代器类型:

  • iterator => T *
  • const_iterator => const T *
  • const iterator => T * const
  • const const_iterator => const T * const

对于指针类型,const在前面表示说不可以通过该指针去修改所指的变量,而const在后面则表示该指针只能指向某个变量,不能修改指针本身,但是可以修改变量。我们在实现迭代器成员类型和函数的时候只需要关注前两者即可,后面的可以按照C++正常的写法来,可以加const的地方直接加上即可。


基于C++11的具体实现

由于我们的重点在于迭代器部分,所以我们尽可能地选取一个简单的数据结构来实现容器,这里我们实现一个双链表。同时我们也假设读者阅读过关于迭代器实现的文章,对迭代器的核心实现有一定的了解。

首先定义一下链表基本的实现:

template <typename T>
class LinkList {
    
    struct ListNodeBase {

        ListNodeBase* m_next;
        ListNodeBase* m_prev;

        ListNodeBase() { reset(); }

        void reset() { m_prev = m_next = this; }
    };

    struct ListNode : ListNodeBase {
        T m_value;
    };

    // 循环链表头结点,next指向第一个元素,prev指向最后一个元素
    ListNodeBase m_header;  
}

接下来是实现迭代器部分,对于很多容器来说,iterator和const_iterator是两个不同类,但是实际上这两个类里面的实现几乎是完全一样的,这也许很容易让人想到继承的写法,但是在C++中我们还有一个更好的方法,那就是使用模板,使用模板的代码量也许会少于使用继承。如果读者是一个非常排斥使用模板的人,不妨尝试着去接受一下,毕竟模板是C++中非常重要的一部分,同时作者也相信在注释和自身基本功到位的情况下,模板的编写和维护也不是非常困难的。

template <bool Const>
struct LinkListIter

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

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

相关文章

MES在数字化工厂中怎么落地?西门子,施耐德为例

在当前制造业高度竞争的环境下&#xff0c;制造企业为了提高生产效率、降低成本以及优化资源利用&#xff0c;需要借助现代化的制造执行系统&#xff08;MES&#xff09;。MES&#xff0c;作为制造业中一种重要的管理信息系统&#xff0c;是数字化工厂中至关重要的一环&#xf…

上位机图像处理和嵌入式模块部署(f103 mcu的按键输入)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 做技术的同学,大部分都会把精力放在技术本身,却忽视了学的东西有什么实际的用途。就拿gpio来说,一般我们点灯也好、做输入也好,最多也就是当成一个实验demo在使用。可是大家有没…

JavaEE---多线程进阶之JUC的常见类

JUC(java.util.conccurrent) : concurrent(并发)是多线程相关的组件 Callable接口 也是一种创建线程的方式,适用于想让某个线程执行逻辑后,返回一个结果 相比之下Runnable不关注结果 改进 以下是Callable的基本使用方法 运行结果: ReentrantLock 信号量Semaphore 也就…

记录关联(笛卡尔积)——kettle开发24

一、记录关联(笛卡尔积) 记录关联就是对两个数据流进行笛卡尔积操作。如下图所示&#xff0c;我们有两组数据分别为aaa和bbb,笛卡尔积后我们生成了4种结果&#xff0c;即2*24条记录。 记录关联(笛卡尔积)需要注意的是我们需要指定一个主步骤。即参考基准的数据 &#xff1a; 二…

安装依赖报-gyp: No Xcode or CLT version detected!

错误 > node-gyp rebuild No receipt for com.apple.pkg.CLTools_Executables found at /. No receipt for com.apple.pkg.DeveloperToolsCLILeo found at /. No receipt for com.apple.pkg.DeveloperToolsCLI found at /. gyp: No Xcode or CLT version detected! gyp ERR!…

信息系统项目管理师0135:输入(8项目整合管理—8.9结束项目或阶段—8.9.1输入)

点击查看专栏目录 文章目录 8.9 结束项目或阶段8.9.1 输入8.9 结束项目或阶段 结束项目或阶段是终结项目、阶段或合同的所有活动的过程。本过程的主要作用: 存档项目或阶段信息,完成计划的工作;释放组织团队资源以开展新的工作。它仅开展一次或仅在项目或阶段的结束点开展。…

11 Goroutine-并发与并行、阻塞与非阻塞

并发 顺序执行&#xff1a;按照事先计划好的顺序&#xff0c;执行完一个操作后&#xff0c;再执行下一个操作。 顺序执行效率不高的原因&#xff1a; 每个操作由多个步骤组成&#xff0c;每个步骤所需要的时间长短不一&#xff0c;有些步骤可能相当耗时。顾客点菜需要时间&a…

辅助科技照亮道路,携手共促盲文书写技能新飞跃

在这个科技日新月异的时代&#xff0c;创新的力量正以前所未有的方式融入我们的日常生活&#xff0c;特别是对于视觉障碍群体而言&#xff0c;技术的每一次进步都是通往更加独立生活的桥梁。今天&#xff0c;让我们聚焦于一款名为“蝙蝠避障”的辅助软件&#xff0c;它不仅为盲…

【Git】使用tortoiseGit

参考视频 【TortoiseGit常用的基本使用教程】 https://www.bilibili.com/video/BV193411h7FP/?share_sourcecopy_web&vd_source77e36f24add8dc77c362748ffb980148 拉取远程代码 创建分支 拉取远端dev分支的代码&#xff1a; 先创建本地的dev分支&#xff1a; 拉取&…

微信小程序中使用vantUI步骤

第一步&#xff0c;配置project.config.json 在setting中新增如下&#xff1a; "packNpmManually": true,"packNpmRelationList": [{"packageJsonPath": "./package.json","miniprogramNpmDistDir": "./"}], 第…

packstack一键部署OpenStack云平台

OpenStack一键部署 文章目录 OpenStack一键部署资源列表基础环境一、基础环境配置1.1、配置时间同步1.2、配置网络1.3、添加hosts绑定1.4、更新系统并安装常用软件 二、使用packstack一键部署OpenStack2.1、Train版YUM源安装2.2、Packstack软件包安装2.3、Packstack一键部署Ope…

搜索网盘资源、在线抠图、动图在线制作、Logo在线制作,这些全都免费!!

搜索网盘资源、免费在线抠图、免费动图在线制作、Logo在线制作&#xff0c;这些都能免费做到&#xff0c;而且效果还真的好&#xff01; 今天&#xff0c;阿星就给大家带来了5个稀缺的神奇网站&#xff0c;这5个神奇网站让你白嫖全网最全干货&#xff01;每一个都是全网最全&a…

【PHP小课堂】PHP中的网络组件相关函数

PHP中的网络组件相关函数 作为一门以 WEB 开发为主战场的编程语言来说&#xff0c;PHP 即使是在目前这个大环境下&#xff0c;依然也是 WEB 领域的头号玩家。我们在网络相关的功能中也提供了许多方便好用的函数组件&#xff0c;而且它们都是不需要安装扩展就能够使用的。今天&a…

面试官:说说Loader和Plugin的区别?编写Loader,Plugin的思路?

一、区别 前面两节我们有提到Loader与Plugin对应的概念&#xff0c;先来回顾下 loader 是文件加载器&#xff0c;能够加载资源文件&#xff0c;并对这些文件进行一些处理&#xff0c;诸如编译、压缩等&#xff0c;最终一起打包到指定的文件中plugin 赋予了 webpack 各种灵活的…

深度学习——自己的训练集——测试模型(CNN)

测试模型 1.导入新图片名称2.加载新的图片3.加载图片4.使用模型进行预测5.获取最可能的类别6.显示图片和预测的标签名称7.图像加载失败输出 导入新的图像&#xff0c;显示图像和预测的类别标签。 1.导入新图片名称 new_image_path 456.jpg2.加载新的图片 new_image cv2.imr…

SQL——SELECT相关的题目(力扣难度等级:简单)

目录 197、上升的温度 577、员工奖金 586、订单最多的客户 596、超过5名学生的课 610、判断三角形 620、有趣的电影 181、超过经理收入的员工 1179、重新格式化部门表&#xff08;行转列&#xff09; 1280、学生参加各科测试的次数 1965、丢失信息的雇员 1068、产品销售分…

【Rust日报】Rust 中的形式验证

文章 - 未来的愿景&#xff1a;Rust 中的形式验证 这篇文章回顾了形式化验证的基本概念&#xff0c;作者展示了如何使用 Hoare triples 来描述和推理程序的正确性&#xff0c;以及如何使用分离逻辑来解决验证的复杂性。文章还解释了为什么 Rust 适用于形式化验证&#xff0c;以…

实现网:评价较好的程序员招聘与接单平台

其实我一直很羡慕敲敲代码就能实现自己的人生梦想的程序员们&#xff0c;想当年&#xff0c;作为初级程序员的我阴差阳错没能走上专业码农的道路&#xff0c;至今仍引以为憾。当然做个程序员并不是件容易的事&#xff0c;今天给大家分享个可通过编程赚钱的靠谱平台——实现网&a…

python max_min标准化

python max_min标准化 max_min标准化sklearn实现max_min标准化手动实现max_min标准化 max_min标准化 Max-Min标准化&#xff08;也称为归一化或Min-Max Scaling&#xff09;是一种将数据缩放到特定范围&#xff08;通常是0到1&#xff09;的标准化方法。这种方法通过线性变换将…

没想到,一个小妙招让桌面运维效率翻倍

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 我的网工朋友大家好。 咱们都知道&#xff0c;电脑用久了&#xff0c;总会出些小毛病&#xff0c;比如桌面图标不显示了&#xff0c;C盘又满了&a…