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 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 3-4-2 deque 容器的迭代器用法 -> 正文阅读

[开发工具]3-4-2 deque 容器的迭代器用法

deque 容器迭代器的类型为随机访问迭代器,deque 模板类提供了表 1 所示这些成员函数,通过调用这些函数,可以获得表示不同含义的随机访问迭代器。
有关迭代器及其类型的介绍,可以阅读《C++ STL迭代器(iterator)》一节,本节不再做具体介绍。

1.deque 支持迭代器的成员函数

表 1 deque 支持迭代器的成员函数

成员函数功能
begin()返回指向容器中第一个元素的正向迭代器;如果是 const 类型容器,在该函数返回的是常量正向迭代器。
end()返回指向容器最后一个元素之后一个位置的正向迭代器;如果是 const 类型容器,在该函数返回的是常量正向迭代器。此函数通常和 begin() 搭配使用。
rbegin()返回指向最后一个元素的反向迭代器;如果是 const 类型容器,在该函数返回的是常量反向迭代器。
rend()返回指向第一个元素之前一个位置的反向迭代器。如果是 const 类型容器,在该函数返回的是常量反向迭代器。此函数通常和 rbegin() 搭配使用。
cbegin()和 begin() 功能类似,只不过其返回的迭代器类型为常量正向迭代器,不能用于修改元素。
cend()和 end() 功能相同,只不过其返回的迭代器类型为常量正向迭代器,不能用于修改元素。
crbegin()和 rbegin() 功能相同,只不过其返回的迭代器类型为常量反向迭代器,不能用于修改元素。
crend()和 rend() 功能相同,只不过其返回的迭代器类型为常量反向迭代器,不能用于修改元素。

C++ 11 新添加的 begin() 和 end() 全局函数也同样适用于 deque 容器。即当操作对象为 deque 容器时,其功能分别和表 1 中的 begin()、end() 成员函数相同,具体用法本节后续会做详细介绍。

表 1 中这些成员函数的具体功能如图 2 所示。
在这里插入图片描述

图 2 迭代器的具体功能示意图

从图 2 可以看出,这些成员函数通常是成对使用的,即 begin()/end()、rbegin()/rend()、cbegin()/cend()、crbegin()/crend() 各自成对搭配使用。其中,begin()/end() 和 cbegin/cend() 的功能是类似的,同样 rbegin()/rend() 和 crbegin()/crend() 的功能是类似的。

值得一提的是,以上函数在实际使用时,其返回值类型都可以使用 auto 关键字代替,编译器可以自行判断出该迭代器的类型

2. deque容器迭代器的基本用法

deque 容器迭代器常用来遍历容器中存储的各个元素。

begin() 和 end() 分别用于指向「首元素」和「尾元素+1」 的位置,下面程序演示了如何使用 begin() 和 end() 遍历 deque 容器并输出其中的元素:

#include <iostream>
#include <deque>
using namespace std;
int main()
{
    deque<int>d{1,2,3,4,5};
    //从容器首元素,遍历至最后一个元素
    for (auto i = d.begin(); i < d.end(); i++) {
        cout << *i << " ";
    }
    return 0;
}
运行结果为:
1 2 3 4 5

前面提到,STL 还提供有全局的 begin() 和 end() 函数,当操作对象为容器时,它们的功能是上面的 begin()/end() 成员函数一样。例如,将上面程序中的第 8~10 行代码可以用如下代码替换:

for (auto i = begin(d); i < end(d); i++) {
    cout << *i << " ";
}

重新编译运行程序,会发现输出结果和上面一致。

cbegin()/cend() 成员函数和 begin()/end() 唯一不同的是,前者返回的是 const 类型的正向迭代器,这就意味着,由 cbegin() 和 cend() 成员函数返回的迭代器,可以用来遍历容器内的元素,也可以访问元素,但是不能对所存储的元素进行修改。

举个例子:

#include <iostream>
#include <deque>
using namespace std;
int main()
{
    deque<int>d{1,2,3,4,5};
    auto first = d.cbegin();
    auto end = d.cend();
    //常量迭代器不能用来修改容器中的元素值
    //*(first + 1) = 6;//尝试修改容器中元素 2 的值
    //*(end - 1) = 10;//尝试修改容器中元素 5 的值
    //常量迭代器可以用来遍历容器、访问容器中的元素
    while(first<end){
        cout << *first << " ";
        ++first;
    }
    return 0;
}
运行结果:
1 2 3 4 5

程序中,由于 first 和 end 都是常量迭代器,因此第 10、11 行修改容器内元素值的操作都是非法的。

deque 模板类中还提供了 rbegin() 和 rend() 成员函数,它们分别表示指向最后一个元素和第一个元素前一个位置的随机访问迭代器,又常称为反向迭代器(如图 2 所示)。

需要注意的是,在使用反向迭代器进行 ++ 或 – 运算时,
++ 指的是迭代器向左移动一位,
– 指的是迭代器向右移动一位,即这两个运算符的功能也“互换”了。

反向迭代器用于以逆序的方式遍历容器中的元素。例如:

#include <iostream>
#include <deque>
using namespace std;
int main()
{
    deque<int>d{1,2,3,4,5};
    for (auto i = d.rbegin(); i < d.rend(); i++) {
        cout << *i << " ";
    }
    return 0;
}
运行结果为:
5 4 3 2 1

crbegin()/crend() 组合和 rbegin()/crend() 组合唯一的区别在于,前者返回的迭代器为 const 类型迭代器,不能用来修改容器中的元素,除此之外在使用上和后者完全相同。

3. deque容器迭代器的使用注意事项

首先需要注意的一点是,迭代器的功能是遍历容器,
在遍历的同时可以访问(甚至修改)容器中的元素,
但迭代器不能用来初始化空的 deque 容器

例如,如下代码中注释部分是错误的用法:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int>values;
    auto first = values.begin();
    //*first = 1;
    return 0;
}

对于空的 deque 容器来说,可以通过 push_back()、push_front() 或者 resize() 成员函数实现向(空)deque 容器中添加元素。

3.1 添加元素后,重新生成迭代器

除此之外,当向 deque 容器添加元素时,deque 容器会申请更多的内存空间,同时其包含的所有元素可能会被复制或移动到新的内存地址(原来占用的内存会释放),这会导致之前创建的迭代器失效。

举个例子:

#include <iostream>
#include <deque>
using namespace std;
int main()
{
    deque<int>d;
    d.push_back(1);
    auto first = d.begin();
    cout << *first << endl;
    //添加元素,会导致 first 失效
    d.push_back(1);
    cout << *first << endl;
    return 0;
}

程序中第 12 行代码,会导致程序运行崩溃,其原因就在于在创建 first 迭代器之后,deque 容器做了添加元素的操作,导致 first 失效。

在对容器做添加元素的操作之后,如果仍需要使用之前以创建好的迭代器,为了保险起见,一定要重新生成。

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-04-30 08:54:24  更:2022-04-30 08:54:28 
 
开发: 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年11日历 -2024/11/14 15:03:39-

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