IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ STL迭代器适配器 -> 正文阅读

[C++知识库]C++ STL迭代器适配器

1.反向迭代器(reverse_iterator)
又称“逆向迭代器”,其内部重新定义了递增运算符(++)和递减运算符(–),专门用来实现对容器的逆序遍历。

reverse_iterator 模板类中共提供了 3 种创建反向迭代器的方法,这里以 vector 容器的随机访问迭代器作为基础迭代器为例。

  1. 调用该类的默认构造方法,即可创建了一个不指向任何对象的反向迭代器,例如:
    std::reverse_iterator<std::vector::iterator> my_reiter;
    由此,我们就创建好了一个没有指向任何对象的 my_reiter 反向迭代器。

  2. 当然,在创建反向迭代器的时候,我们可以直接将一个基础迭代器作为参数传递给新建的反向迭代器。例如:
    纯文本复制
    //创建并初始化一个 myvector 容器
    std::vector myvector{1,2,3,4,5};
    //创建并初始化 my_reiter 迭代器
    std::reverse_iterator<std::vector::iterator> my_reiter(myvector.end());

  3. 除了第 2 种初始化方式之外,reverse_iterator 模板类还提供了一个复制(拷贝)构造函数,可以实现直接将一个反向迭代器复制给新建的反向迭代器。比如:
    纯文本复制
    //创建并初始化一个 vector 容器
    std::vector myvector{1,2,3,4,5};
    //调用复制构造函数初始化反向迭代器的 2 种方式
    std::reverse_iterator<std::vector::iterator> my_reiter(myvector.rbegin());
    //std::reverse_iterator<std::vector::iterator> my_reiter = myvector.rbegin();

reverse_iterator 模板类还提供了 base() 成员方法,该方法可以返回当前反向迭代器底层所使用的基础迭代器。

2.安插型迭代器(inserter或者insert_iterator)
通常用于在容器的任何位置添加新的元素,需要注意的是,此类迭代器不能被运用到元素个数固定的容器(比如 array)上。

back_insert_iterator
在指定容器的尾部插入新元素,但前提必须是提供有 push_back() 成员方法的容器(包括 vector、deque 和 list)。
front_insert_iterator
在指定容器的头部插入新元素,但前提必须是提供有 push_front() 成员方法的容器(包括 list、deque 和 forward_list)。
insert_iterator
在容器的指定位置之前插入新元素,前提是该容器必须提供有 insert() 成员方法。

C++ STL 标准库中,提供有 push_back() 成员方法的容器包括 vector、deque 和 list。
C++ STL 标准库中,提供有 push_front() 成员方法的容器,仅有 deque、list 和 forward_list。
需要说明的是,该类型迭代器的底层实现,需要调用目标容器的 insert() 成员方法。但幸运的是,STL 标准库中所有容器都提供有 insert() 成员方法,因此 insert_iterator 是唯一可用于关联式容器的插入迭代器。

和反向迭代器不同,back_insert_iterator 插入迭代器的定义方式仅有一种,其语法格式如下:
std::back_insert_iterator back_it (container);
其中,Container 用于指定插入的目标容器的类型;container 用于指定具体的目标容器。

举个例子:
//创建一个 vector 容器
std::vector foo;
//创建一个可向 foo 容器尾部添加新元素的迭代器
std::back_insert_iterator< std::vector > back_it(foo);
std::insert_iterator insert_it (container,it);
其中,Container 表示目标容器的类型,参数 container 表示目标容器,而 it 是一个基础迭代器,表示新元素的插入位置

3.流迭代器(istream_iterator / ostream_iterator)
流缓冲区迭代器(istreambuf_iterator / ostreambuf_iterator)
输入流迭代器用于从文件或者键盘读取数据;相反,输出流迭代器用于将数据输出到文件或者屏幕上。
输入流缓冲区迭代器用于从输入缓冲区中逐个读取数据;输出流缓冲区迭代器用于将数据逐个写入输出流缓冲区。

输入流缓冲区迭代器(istreambuf_iterator):从输入流缓冲区中读取字符元素;
输出流缓冲区迭代器(ostreambuf_iterator):将连续的字符元素写入到输出缓冲区中。

流缓冲区迭代器和流迭代器最大的区别在于,前者仅仅会将元素以字符的形式(包括 char、wchar_t、char16_t 及 char32_t 等)读或者写到流缓冲区中,由于不会涉及数据类型的转换,读写数据的速度比后者要快。

  1. 通过调用 istreambuf_iterator 模板类中的默认构造函数,可以创建一个表示结尾的输入流缓冲区迭代器。要知道,当我们从流缓冲区中不断读取数据时,总有读取完成的那一刻,这一刻就可以用此方式构建的流缓冲区迭代器表示。

举个例子:
std::istreambuf_iterator end_in;
其中,<> 尖括号中用于指定从流缓冲区中读取的字符类型。

  1. 当然,我们还可以指定要读取的流缓冲区,比如:
    std::istreambuf_iterator in{ std::cin };
    除此之外,还可以传入流缓冲区的地址,比如:
    std::istreambuf_iterator in {std::cin.rdbuf()};
    其中,rdbuf() 函数的功能是获取指定流缓冲区的地址。
    无论是传入流缓冲区,还是传入其地址,它们最终构造的输入流缓冲区迭代器是一样的。

创建输出流缓冲区迭代器的常用方式有以下 2 种:

  1. 通过传递一个流缓冲区对象,即可创建一个输出流缓冲区迭代器,比如:
    std::ostreambuf_iterator out_it (std::cout);
    同样,尖括号 <> 中用于指定要写入字符的类型,可以是 char、wchar_t、char16_t 以及 char32_t 等。

  2. 还可以借助 rdbuf(),传递一个流缓冲区的地址,也可以成功创建输出流缓冲区迭代器:
    std::ostreambuf_iterator out_it (std::cout.rdbuf());

4.移动迭代器(move_iterator)
此类型迭代器是 C++ 11 标准中新添加的,可以将某个范围的类对象移动到目标范围,而不需要通过拷贝去移动。
move_iterator 迭代器适配器,又可简称为移动迭代器,其可以实现以移动而非复制的方式,将某个区域空间中的元素移动至另一个指定的空间。

如何将const_iterator转换为iterator类型迭代器?
对于 C++ STL 标准库中的这 4 种基础迭代器来说,C++ 编译器的隐式转换仅支持以下 2 种情况:
将 iterator 类型的迭代器隐式转换为 const_iterator 类型的迭代器;
将 reverse_iterator 类型的迭代器隐式转换为 const_reverse_iterator 类型的迭代器。
注意,以上 2 种隐式转换是单向的,即编译器只支持从 iterator 转换为 const_iterator,从 reverse_iterator 转换为 const_reverse_iterator,但不支持逆向转换。

//将 const_iterator 转换为 iterator
advance(iter, distance<cont::const_iterator>(iter,citer));
//将 const_reverse_iterator 转换为 reverse_iterator
advance(iter, distance<cont::const_reverse_iterator>(iter,citer));

其中,citer 为指向某个容器(比如 cont)任意位置的 const_iterator(或者 const_reverse_iterator)类型迭代器,而 iter 通常初始为指向 cont 容器中第一个元素的 iterator(或者 reverse_iterator)类型迭代器。通过套用此格式,最终 iter 会变成一个指向和 citer 一样的 iterator(或者 reverse_iterator)类型迭代器。
注意,在使用 distance() 函数时,必须额外指明 2 个参数为 const 迭代器类型,否则会因为传入的 iter 和 citer 类型不一致导致 distance() 函数编译出错。
该实现方式的本质是,先创建一个迭代器 citer,并将其初始化为指向容器中第一个元素的位置。在此基础上,通过计算和目标迭代器 iter 的距离(调用 distance()),将其移动至和 iter 同一个位置(调用 advance()),由此就可以间接得到一个指向同一位置的 iter 迭代器。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 09:26:01  更:2021-08-06 09:28:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 8:06:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码