迭代器适配器(iterator adapters)

C++ STL和泛型编程(三)----适配器(Adapters) C++ STL和泛型编程(三)----适配器(Adapters)一、作用及类别二、Container Adapters三、Functor Adapters- binder2nd- not1- bind四、Iterator Adapters- reverse_iterator- inserter(注意不是insert)五、X adapters- ostream_iterator 一、作用及类别 Adapter是将某个已经存在的东西改造一下,如改下接口(两个参数的改为一个参数)或改下函数名称之类的。 在编程技术 阅读详情

前一节中我们讨论了主要的几个迭代器,但是那几个迭代器都是定义于STL中的标准容器,用法也只能针对标准容器,比较局限。在不断的演变中,STL的爱好者扩充了迭代器的内容,他们在迭代器的基础上发展而来,叫迭代器适配器,他提供了更多的操作功能,也不仅仅局限于容器,还可以应用于更多方面。

首先看看迭代器适配器的分支图:

 

以上的迭代器都叫做迭代器适配器,正如容器有标准容器和容器适配器,仿函数有标准仿函数和仿函数适配器,这里的迭代器适配器也是一样的道理。显然他们都是在原有迭代器的基础之上发展而来的,所以基础迭代器拥有的他们都拥有,包括上一节所讲的几个重要迭代器函数。下面我们将要一一的来讲解上图中的迭代器适配器。

1:逆向迭代器

逆向迭代器是一种适配器,他通过重新定义递增递减运算符使其行为恰好相反。这样一来使用这种迭代器算法将会逆向次序进行。

定义方式:

Vector<int>::reserve_iterator rit;

而且首位置为rbegin(),也就是原来的末位,末位置为rend(),也就是原来的首位;

请看下面一段代码:

vector<int> bec;

for(int i=1;i<11;i++)

vec.push_back(i);

for_each(vec.rbegin(),vec.rend(),print);

//这里假定print为已经定义的输出函数

这样输出结果可想而知,输出的当然是10开始的逆序。

请注意看接下来的例子,他对你理解逆向迭代器至关重要。

 

结果:

 

这就奇怪了,同样是pos所指的位置,该位置为5,为什么利用逆向迭代器输出来以后就变成4了?现在我们需要讨论一个问题,从输出中我们知道结果已经变了,但是到底是迭代器所指的位置变了,还是迭代器的位置没变,而是逻辑位置发生了改变。这里读者可以自己猜一下。

接下来,废话不多说,直接上图!!!

 

有了这图我就不需要再说什么了,相信大家已经对逆向迭代器理解了.下面我们将要介绍一个STL算法库中针对逆向迭代器的函数。

Base()函数

该函数将逆向迭代器转回正常的迭代器。在上面一个例子中已经用到了。结果也已经列出,不在多说。

对于逆向迭代器,就这些主要点的内容,改迭代器主要用来逆向输出或者操作,只在一些特定的地方可以更好的发挥,但是也要掌握好他的用法,有时候处理起来还是比较方便。

2:输入流输出流迭代器

1:输出流迭代器

输出流迭代器也是一种适配器,他由输出迭代器演变而来,赋予了写入到输出流中的能力,对于输入输出流这两个迭代器,我认为最好的方式就是通过实例来说明问题,可以更好的学到用法。

输出流迭代器定义:

Ostream_iterator<type>(ostream,delim);

或Ostream_iterator<type>(ostream,);

上面ostream代表需要为他的构造函数提供一个输出流对象,我们一般是用cout,delim是一个字符串指针,表示以它的内容来隔开输出的内容。

Iter++ 和++iter :表示迭代器往前移动,对下一个流单位进行写入。

下面直接看这个例子。

 

 

可以看到利用输出流迭代器输出单个元素或者是输出整个容器都是十分方便的,其中的copy函数是把begin和end之间的部分复制到inWriter中,实际就是复制到输出流中,所以整个容器都输出来了。这种方式在容器中是最常用的方法。

2:输入流迭代器

对于输入流迭代器,就是利用算法读取输入流中的数据,输入输出天生就是一对拍档,但是输入流却要比输出流复杂一点,因为读取出来本来就要比写入进去复杂。

定义:

利用构造函数构造一个输入流迭代器的时候也需要传递一个输入流对象作为参数,我们使用cin进行读取,但是读取动作可能发生的错误:读取数据失败或者是读到了文件的尾部,因此我们利用了一个end_of_stream迭代器,他可以由istream_iterator的默认构造函数生成。

Istream_iterator:     istream_iterator<type> inRead(cin);

End_of_stream:      istream_iterator<type> inReadEOF;

只要输入流迭代器有任何一次读取失败,他就会变成end_of_stream迭代器,所以每次读取你都应该把他们两个拿来比较一番。

还有个值得说明的是,输入流迭代器的构造函数一旦构造他,就会马上打开输入流缓冲区,有时候会在构造之后马上读取一个元素,所以尽量不要过早的定义它,有可能导致第一个元素无法传回。当然有些版本中会延缓这个动作,不会马上读取,这个作个了解就好。真要出现了我们也无法解决。

下面直接看例子:

 

可以看到,输入的是那几个数字只出现了前面几个,那是因为我们构造函数传递的类型参数是int 所以她读取到字符的时候导致读取错误,迭代器变为end_of_stream迭代器,循环结束。

对于输入流输出流迭代器,希望大家多用,多熟悉,本节只是提及了一下最基本的,并不深入,但是你会发现处理很多问题还是很方便的,在以后有专门的章节介绍stream的那些知识。

3:安插型迭代器

Insert 迭代器用来将赋值和复制操作转化为安插操作,(至于这句话是什么意思,我来分析一下,因为容器的操作都是赋值和复制操作,都会产生临时对象,所以效率不高,利用安插型迭代器直接插入一个值,效率会更好,而且在某些方面,不仅仅是效率问题了。这就是安插型迭代器的理念。)

在介绍安插型迭代器之前,我们来看看copy算法的源代码:

 

(只是模拟的,也许细节有出入,大概就这样)

可以看到,copy从算法起点开始不断循环,不断赋值给to_pos,直到循环结束。于是有初学者直到了copy算法之后就开始这样使用,代码如下:

 

 

结果大家可以猜想一下,这里我直接贴出来:

有经验的一看就是内存错误,也许是越界咯!

那么到底是什么原因勒?我们知道copy算法是依次赋值,我相信只要学过编程的都知道,要想给一个变量赋值,首先那个变量得有地址吧!要分配空间吧,不能给一个不存在的变量赋值吧,那么在这里,a容器使用默认构造函数,构造的是一个空容器,不存在任何长度,也就没分配那么多空间,如何存储得下b的元素,失败是必然的。

这里顺便提一句, 在标准的C++算法库中,没有任何一个算法在不借助外来帮助的情况下可以改变容器的大小,注意我说的是算法库中,不是指push_back这一类容器自带的函数。

所以在这里,我们的安插型迭代器出现用途了,这就是上面所说的借助的外来帮助,安插性容器本来自带了分配内存并且插入的功能

改写后的程序,代码如下:

在代码中我只是修改了其中一个地方, 利用了后插迭代器的便捷函数,也许大家还对安插迭代器陌生,前面这一切只是个铺垫,下面我们真正的开始介绍安插迭代器。

安插性迭代器分类:

1:前插迭代器。(默认为只在最前面插入)

2:后插迭代器。(默认为只能在最后插入)

3:插入迭代器(也就是可以指出插入位置的迭代器)

实际上他们都是调用相应容器的插入函数。

每一种迭代器都可以由一个便捷函数加以生成和初始化(便捷函数不陌生吧,pair模版和make_pair函数)

请记住下面这个表:

 

名称

迭代器类名 class

调用相应的函数

便捷函数

后插迭代器

back_insert_iterator

Push_back(value)

Back_inserter

前插迭代器

front_insert_iterator

Push_front(value)

Front_inserter

插入迭代器

Insert_iterator

Insert(pos,value)

Inserter

 

对于迭代器的举例,这里我只列出后插的即可,代码如下:

 

 

 

从这个程序中我们可以看到,后插迭代器的初始化,首先需要指明容器类型,然后还要赋一个具体的容器,使他们绑定在一起,初始化方法需要掌握。接下来利用的是便捷函数back_inserter的用法,可以看出他比较方便,最后一段代码表示利用copy算法把本身前面的一段插入到后面一段,但是也许有人不明白,为什么最后一个数值出错了勒?大家可以考虑一下这个原因是什么,上面一个例子我已经说了,安插迭代器可以在不分配内存的情况下直接插入,所以这里只是错误,但不至于程序崩溃。在对容器自身进行插入时最好是分配好足够的空间,因为这样可以使原有的迭代器固定下来,执行插入也不容易出错。如果不固定容器大小则他的迭代器会经常改变,这也就是导致错误的原因。

解决办法,在上面的代码中加入这一行,我相信大家都知道加在哪:

coll.reserve(2*coll.size()); //把容器长度重置为原来的两倍。

 

 

 

安插型迭代器本身的内容就不多,把前面的理解了就可以了,至于更高级的用法,这需要与算法库中的函数结合才能发挥出效果。

迭代器适配器就到这里,我们主要分析了三种适配器的用法和注意点,合理的运用适配器会使程序更加方便简洁,本节我略去了几个知识,一个是为迭代器编写泛型函数,一个是使用自定义的迭代器,这些过于高级,我自己也一知半解,所以不能误人子弟,以后有机会我会补充出来的。

 

C++ STL迭代器深度解析:从核心概念到自定义实现与实战应用 迭代器是泛型编程中的核心抽象概念,它提供了一种统一访问数据序列元素的方法,而不依赖于底层具体的数据结构(如数组、链表或树)。其工作原理是通过定义一组标准操作(如解引用、自增、比较)来封装对元素的访问和遍历逻辑,从而将算法与数据结构解耦。这种设计的技术价值在于实现了算法的高度复用性和数据结构的独立性,是编写高效、通用代码的基石。在C++ STL中,迭代器广泛应用于各种算法(如排序、查找、变换)和容器(如vector、list、map)的交互场景。本文以C++ STL迭代器为焦点,深入探讨其分类体系、特性萃取机 阅读详情

相关推荐

通过 Android Framework 调用高通 Perf HAL 实现 CPU/GPU 动态调频策略

本文详细介绍了如何通过Android Framework调用高通Perf HAL实现CPU/GPU动态调频策略。文章涵盖HAL交互原理、环境搭建、Power HAL接口实现、PerformanceHintManager应用及温度功耗平衡处理,帮助开发者安全高效地进行性能优化,避免直接操作底层硬件的风险。

keras9composer的博客 254

【STL十三】适配器——迭代器适配器

3种迭代器适配器:分别是**反向迭代器**适配器、**插入型迭代器**适配器、**移动迭代器**适配器。 2种流迭代器:**流迭代器**、**流缓冲区迭代器**

junxuezheng的博客 1239

【无人机对抗】基于matlab无人机红蓝对抗仿真【含Matlab源码 4436期】

无人机红蓝对抗仿真 完整代码,包运行;可提供运行操作视频!适合小白!

Matlab3024528700的博客 1378

C++ STL迭代器适配器(详解)

本节讲解了 3 种插入迭代器,虽然它们都可以借助重载的赋值运算符,实现向目标容器的指定位置插入新元素,但在实际应用中,它们通常和 copy() 函数连用,即作为 copy() 函数的第 3 个参数。有关 copy() 函数的具体用法,由于不是本节重点,这里不再赘述,后续章节会做详细讲解。

qq_25218501的博客 1031

用PLECS搞定三相逆变器电流环:从传递函数推导到PI参数整定的保姆级教程

本文提供了一份详细的PLECS教程,指导如何从传递函数推导到PI参数整定,实现三相逆变器电流环的闭环控制。通过坐标变换、控制器设计和仿真验证等步骤,帮助工程师快速掌握电流环控制技术,提升电力电子系统的稳定性和可靠性。

weixin_27102543的博客 398

数据库1:数据库创建与管理(头歌云课)

在 Windows 系统中,可以直接通过 SQLServer 的应用程序连接数据库,不过很多时候在生产环境下,我们需要通过命令行来连接数据库。两个数据库,数据库名分别为 TestDb 和 MyDb 的数据库,注意先后顺序。为了完成本关任务,你需要掌握:1.如何在 Linux 系统中连接 SQLServer 数据库,2.如何创建数据库。连接的数据库是本地数据库,用户名是 sa ,密码是 '

weixin_60530224的博客 2314

【STL十二】适配器——容器适配器

适配器种类:容器适配器、迭代器适配器、函数适配器

junxuezheng的博客 1743

高项49个过程,输入、工具技术、输出的思维导图

为了制定项目章程的管理方法主要是采用了数据收集技术,例如通过头脑风暴,通过召集主题专家和团队成员收集信息、解决方案,并在短时间内获得大量创意,并对大量创意进行分析和排序,选出最优化最适合本项目方案,并对项目成员的不同差异观点,进行了引导和对冲突的管理,最终有助于项目干系人的目标、成功标准的内容达成一致意见,形成完善的项目章程。在本过程中得到项目章程,在制定项目章程中需要包括信息有:项目名称、项目目标、项目总里程碑进度表、项目经理、主要干系人及财务预算信息。本过程在仅开展一次,或仅在项目的预定义点开展。

Legend_Jiang的博客 6179

C++标准库分析总结(十一)——<适配器>

C++标准库分析总结(九)——<适配器、istream_iterator、ostream_iterator、bind>

梦心之魂的博客 1775

在zcu102开发板上使用PetaLinux运行Qt程序

请注意,上述步骤只是一个概述,并且可能需要根据特定的开发环境和要求进行适当的调整。如果你是一个初学者或者对于这些领域不太熟悉,建议在尝试之前阅读相关的文档和教程,或者寻求专业人士的帮助。在"Projects"菜单中,选择"Build & Run"选项,并在"Build"步骤中选择正确的工具链。注意:如果Qt程序依赖于其他库文件,需要将这些库文件一起复制到PetaLinux工程的根文件系统目录中,并在Qt程序中正确地配置库文件路径。如果一切顺利,PetaLinux系统将启动,并自动运行Qt程序。

UhxzCombined的博客 698

mapbox高阶,加载倾斜摄影

本文详细介绍如何基于mapbox-gl v3.8.0版本实现倾斜摄影的加载,亲测可用。希望能帮助到您。一起学习,加油!加油!

我哎GIS博客 342

详解反向迭代器适配器

首先简单介绍反向迭代器适配器,然后对其进行模拟实现。

melonyzzZ的博客 306

LoRA 完整解析:从理论到实践

LoRA(低秩适应)是一种高效的大模型微调方法,通过添加少量可训练参数(低秩矩阵)来适配新任务,避免全参数微调的高成本。其核心是将权重更新ΔW分解为两个小矩阵B×A的乘积,大幅减少训练参数量(仅0.1-1%)。LoRA基于内在维度假设,通过低秩约束捕捉核心任务信息,兼具效率与效果。实际应用中,常用配置为秩r=16-32,目标模块选择注意力层的q_proj和v_proj,学习率比全参数微调大10倍(约1e-4)。优势包括参数高效(内存降低60-80%)、多任务适配灵活、保留预训练知识等,已成为大模型微调的主流

echo的博客 1410

三 迭代器(三)迭代器适配器(Iterator adapters)

一 迭代器适配器(Iterator adapters) 迭代器是一个纯粹抽象概念:任何东西,只要行为类似迭代器,它就是一个迭代器。 C++标准程序库提供了数个预先定义的特殊迭代器,即所谓迭代器适配器,它不仅起辅助作用,还能赋予整个迭代器抽象概念更强大的能力。 使用时需包含头文件。其中Insert iterators和Reverse iterators定义于中,Stream iterators

linux系统、网络编程和分布式计算 1074

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

STL与泛型编程<十>:迭代器适配器(Iterator Adapters)之逆向迭代器

此类迭代器可以使得算法能够以逆向(reverse mode)模式,安插模式(insert mode)进行工作,也可以流(streams)的模式搭配工作逆向迭代器reverse迭代器是一种适配器,重新定义递增运算和递减运算,使其行为正好倒置,所有标准容器都允许使用reverse迭代器来遍历元素,例子#include <iostream> #include <list> #include <itera

耗纸的博客 530

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

STL的六大组件

STL的六大组件

C++的知识 211

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【C++】STL六大组件之一——适配器(adapters)

关于c++适配器的学习总结

Pursue quality, not quantity. 3849

STL 简单 iterator adapters 的实现

1. 简介 配接器(adapters)在STL组件的灵活组合上,扮演者轴承、转换的角色。Adapters事实上是一种设计模式(design pattern)。 百度百科对adapters模式的解释: 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。——Gang of Four          在STL的体系中,有

chengonghao的博客 1850

STL配接器原理详解——迭代器配接器(iterator adapters)

一、配接器介绍 STL提供的各种配接器中: 改变仿函数接口者:称为function adapter 改变容器接口者:称为container adapter 改变迭代器接口者:称为iterator adapter 二、迭代器配接器介绍 待续 ...

董哥的黑板报 1741

C++中的iterator adapters

C++标准库提供了几种预定义的特殊迭代器,迭代适配器。下面我们介绍常用的三种迭代适配器:插入迭代器,流迭代器,反向迭代器。     1.插入迭代器(insert iterator)     插入迭代器可以使迭代器进入插入模式,同时解决了copy算法进行复制时目标空间不够大的情况。     C++标准库中有三种插入迭代器:back_inserter(container),front_inserter

a simplicity of zone 1042

STL --- 七. 适配器(Adapters)

介绍STL的适配器(Adapters),以及几种分类:迭代器适配器、容器适配器,以及函数适配器。

bigger_belief的博客 1194

(十五)适配器adapters

适配器简介 adapter更像是一个换肤工程,如把参数的个数改一下或者把函数的名称改一下。 适配器根据它所改的对象分为三类 函数适配器 迭代器适配器 容器适配器 适配器更像是一个桥梁,只是修改接口,并不自己实现真正的功能 适配器都是用内含的方式实现对另一个东西的控制 容器适配器stack、queue 二者都内含了一个sequence,默认是deque。将容器的所有接口封装为个别的几个,或者将容器的接口封装后修改其名称 template <class T, class Sequence =

Mirevas的博客 176

【STL】适配器(adapters)

定义:将一个class的接口转换为另一个class的接口,使原本因接口不兼容而不能合作的classes,可以一起运作。适配器扮演者轴承、转换器的角色。 分类: 1、容器适配器:改变容器接口。 STL提供两个容器迭代器:queue和stack。它们都是修饰deque后成为另一种风貌的容器。 2、迭代器适配器:改变迭代器接口。 Insert Iterator:将容器绑

Nestle的专栏 2937

DS container adapters <B> can not use iterator 1/99

容器适配器的主要目的是强制用户只能按照特定的抽象数据类型(ADT)规则来操作数据,从而保证数据结构的完整性和行为的正确性。必须是 LIFO(后进先出)。允许使用迭代器意味着你可以访问和修改栈中任何位置的元素,这会破坏 LIFO 的特性。必须是 FIFO(先进先出)。迭代器会允许你从中间删除或修改元素,破坏 FIFO 的原则。必须是堆结构。迭代器会暴露底层数组的无序状态,并且允许你修改某个元素而不触发堆的重新调整,这会破坏优先级队列的排序保证。

weixin_44525183的博客 775

STL 源码剖析:配接器 (stack,queue,插入迭代器,反向迭代器,流迭代器)

​ STL 所提供的各种配接器中,改变仿函数 (functors) 接口者,我们称为 function adapter,改变容器 (containers) 接口者,我们称为 container adapter,改变迭代器 (iterators) 接口者,我们称为 iterator adapter。 // // ​ 应用于容器:STL 所提供的两个容器,queue 和 stack,其实都是一种配接器...

Error Man 的博客 352

六 配接器(二)iterator adapters

一 概述(纵使千变化万,始终是扮演迭代器的部分作用,所以只能出现在需要迭代器的地方): STL提供的迭代器配接器包括:insert iterator、reverse iterator和stream iterator。 使用时需包含头文件。其中Insert iterators和Reverse iterators定义于中,Stream iterators定义于头文件中。

linux系统、网络编程和分布式计算 806
上一篇: C++ stl之迭代器(iterator)
下一篇: 贪心算法详解
lloil
博客等级 码龄14年 382粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值