C++标准模板(STL)- 迭代器库-迭代器适配器 - 逆序遍历的迭代器适配器

迭代器库-迭代器适配器

迭代器库提供了五种迭代器的定义,同时还提供了迭代器特征、适配器及相关的工具函数。

迭代器分类


迭代器共有五 (C++17 前)六 (C++17 起)种:遗留输入迭代器 (LegacyInputIterator) 、遗留输出迭代器 (LegacyOutputIterator) 、遗留向前迭代器 (LegacyForwardIterator) 、遗留双向迭代器 (LegacyBidirectionalIterator) 、遗留随机访问迭代器 (LegacyRandomAccessIterator) ,及 遗留连续迭代器 (LegacyContiguousIterator) (C++17 起)。

迭代器的分类的依据并不是迭代器的类型,而是迭代器所支持的操作。换句话说,某个类型只要支持相应的操作,就可以作为迭代器使用。例如,完整对象类型指针支持所有遗留随机访问迭代器 (LegacyRandomAccessIterator) 要求的操作,于是任何需要遗留随机访问迭代器 (LegacyRandomAccessIterator) 的地方都可以使用指针。

迭代器的所有类别(除了遗留输出迭代器 (LegacyOutputIterator) 和遗留连续迭代器 (LegacyContiguousIterator) )能组织到层级中,其中更强力的迭代器类别(如遗留随机访问迭代器 (LegacyRandomAccessIterator) )支持较不强力的类别(例如遗留输入迭代器 (LegacyInputIterator) )的所有操作。若迭代器落入这些类别之一且亦满足遗留输出迭代器 (LegacyOutputIterator) 的要求,则称之为可变 迭代器并且支持输入还有输出。称非可变迭代器为常迭代器。

逆序遍历的迭代器适配器

std::reverse_iterator
template< class Iter >

class reverse_iterator : public std::iterator<
                           typename std::iterator_traits<Iter>::iterator_category,
                           typename std::iterator_traits<Iter>::value_type,
                           typename std::iterator_traits<Iter>::difference_type,
                           typename std::iterator_traits<Iter>::pointer,

                           typename std::iterator_traits<Iter>::reference >
(C++17 前)

template< class Iter >
class reverse_iterator;

(C++17 起)

std::reverse_iterator 是一个反转给定迭代器方向的迭代器适配器。换言之,提供双向迭代器时, std::reverse_iterator 产生一个新的迭代器,它从底层的双向迭代器所定义的序列的末尾移动到开端。

对于从迭代器 i 构造的 r 逆向迭代器,关系 &*r == &*(i-1) 始终为 true (只要 r 可解引用);从而构造自末尾后一位置的迭代器的逆向迭代器解引用到序列的最后元素。

这是标准库容器的成员函数 rbegin()rend() 所返回的迭代器。

成员类型

成员类型定义
iterator_typeIter
iterator_concept
(C++20 起)
Iter 实现 std::random_access_iterator ,则为 std::random_access_iterator_tag 。否则为 std::bidirectional_iterator_tag
iterator_category

std::iterator_traits<Iter>::iterator_category

(C++20 前)

若 std::iterator_traits<Iter>::iterator_category 实现 std::derived_from<std::random_access_iterator_tag> ,则为 std::random_access_iterator_tag 。否则为不更改的 std::iterator_traits<Iter>::iterator_category

(C++20 起)
value_type

std::iterator_traits<Iter>::value_type

(C++20 前)

std::iter_value_t<Iter>

(C++20 起)
difference_type

std::iterator_traits<Iter>::difference_type

(C++20 前)

std::iter_difference_t<Iter>

(C++20 起)
pointerstd::iterator_traits<Iter>::pointer
reference

std::iterator_traits<Iter>::reference

(C++20 前)

std::iter_reference_t<Iter>

(C++20 起)

要求通过从 std::iterator<std::iterator_traits<Iter>::iterator_category
, std::iterator_traits<Iter>::value_type
, std::iterator_traits<Iter>::difference_type
, std::iterator_traits<Iter>::pointer
, std::iterator_traits<Iter>::reference
> 继承获得成员类型 iterator_categoryvalue_typedifference_typepointerreference

(C++17 前)

成员函数

(构造函数)

构造新的迭代器适配器
(公开成员函数)

operator=

赋值另一迭代器
(公开成员函数)

base

访问底层迭代器
(公开成员函数)

operator*operator->

访问指向的元素
(公开成员函数)

operator[]

按索引访问元素
(公开成员函数)

operator++operator++(int)operator+=operator+operator--operator--(int)operator-=operator-

推进或回退迭代器
(公开成员函数)

成员对象

成员名称定义
current (受保护成员对象)base() 迭代器的副本

非成员函数

make_reverse_iterator

(C++14)

创建拥有从实参推出的类型的 std::reverse_iterator
(函数模板)

operator==operator!=operator<operator<=operator>operator>=

比较底层迭代器
(函数模板)

operator+

令迭代器前进
(函数模板)

operator-

计算两个迭代器适配器间的距离
(函数模板)

iter_move

(C++20)

转型解引用调整后的底层迭代器的结果为其所关联的右值引用类型
(函数模板)

iter_swap

(C++20)

交换二个调整后的底层迭代器所指向的对象
(函数模板)

注意

std::reverse_iterator 不可作用于返回到成员对象引用的迭代器(是谓“隐匿迭代器”)。隐匿迭代器的一个例子是 std::filesystem::path::iterator 。

调用示例

#include <iostream>
#include <string>
#include <iterator>
#include <deque>
#include <algorithm>
#include <time.h>

struct Cell
{
    int x;
    int y;

    Cell() = default;
    Cell(int a, int b): x(a), y(b) {}

    Cell &operator +=(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator +(const Cell &cell)
    {
        x += cell.x;
        y += cell.y;
        return *this;
    }

    Cell &operator *(const Cell &cell)
    {
        x *= cell.x;
        y *= cell.y;
        return *this;
    }

    Cell &operator ++()
    {
        x += 1;
        y += 1;
        return *this;
    }

    bool operator <(const Cell &cell) const
    {
        if (x == cell.x)
        {
            return y < cell.y;
        }
        else
        {
            return x < cell.x;
        }
    }

    bool operator ==(const Cell &cell) const
    {
        return x == cell.x && y == cell.y;
    }
};

std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
    os << "{" << cell.x << "," << cell.y << "}";
    return os;
}

template< class BDIter >
void alg(BDIter, BDIter, std::input_iterator_tag)
{
    //遗留输入迭代器
    std::cout << "alg() called for input iterator" << std::endl;
}

template< class BDIter >
void alg(BDIter, BDIter, std::output_iterator_tag)
{
    //遗留输出迭代器
    std::cout << "alg() called for output iterator" << std::endl;
}

template< class BDIter >
void alg(BDIter, BDIter, std::forward_iterator_tag)
{
    //遗留向前迭代器
    std::cout << "alg() called for forward iterator" << std::endl;
}

template< class BDIter >
void alg(BDIter, BDIter, std::bidirectional_iterator_tag)
{
    //遗留双向迭代器
    std::cout << "alg() called for bidirectional iterator" << std::endl;
}

template <class RAIter>
void alg(RAIter, RAIter, std::random_access_iterator_tag)
{
    //遗留随机访问迭代器
    std::cout << "alg() called for random-access iterator" << std::endl;
}

template< class Iter >
void alg(Iter first, Iter last)
{
    alg(first, last,
        typename std::iterator_traits<Iter>::iterator_category());
}

int main()
{
    std::string string = "Hello, world";
    std::reverse_iterator<std::string::iterator> reverse_iterator = string.rbegin();
    string[7] = 'O'; // 以 'O' 替换 'o'
    string += 7; // 迭代器现在指向 'O'
    alg(reverse_iterator, reverse_iterator);
    std::cout << "string:   " << string << std::endl;
    std::string reverse_string(reverse_iterator, string.rend());
    std::cout << "reverse_string:   " << reverse_string << std::endl;
    std::cout << std::endl;

    std::mt19937 g{std::random_device{}()};

    srand((unsigned)time(NULL));;

    std::cout << std::boolalpha;

    auto generate = []()
    {
        int n = std::rand() % 10 + 100;
        Cell cell{n, n};
        return cell;
    };

    {
        std::deque<Cell> deque1(6);
        std::generate(deque1.begin(), deque1.end(), generate);
        std::cout << "deque1 :  ";
        std::copy(deque1.begin(), deque1.end(), std::ostream_iterator<Cell>(std::cout, " "));
        std::cout << std::endl;

        std::cout << "deque1 reverse :  ";
        for (std::deque<Cell>::reverse_iterator rit = deque1.rbegin(); rit != deque1.rend(); rit++)
        {
            std::cout << *rit << " ";
        }
        std::cout << std::endl;
        alg(deque1.rbegin(), deque1.rend());
    }

    return 0;
}

输出

alg() called for random-access iterator
string:   Hello, Oorld
reverse_string:   dlroO ,olleH

deque1 :  {109,109} {106,106} {101,101} {107,107} {103,103} {102,102}
deque1 reverse :  {102,102} {103,103} {107,107} {101,101} {106,106} {109,109}
alg() called for random-access iterator

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Partially Spoofed Audio Detection论文介绍(ICASSP 2024)

An Efficient Temporary Deepfake Location Approach Based Embeddings for Partially Spoofed Audio Detection 论文翻译名&#xff1a;一种基于部分欺骗音频检测的基于临时深度伪造位置方法的高效嵌入 摘要&#xff1a; 部分伪造音频检测是一项具有挑战性的任务&#xff0…

【Python特征工程系列】基于相关性分析的特征重要性分析(案例+源码)

这是我的第295篇原创文章。 一、引言 相关性分析提供了一种简单而直观的方法来初步筛选特征。通过计算特征与目标变量之间的相关系数&#xff0c;我们能够快速地评估各个特征与预测目标之间的线性关系强度。 在统计学中&#xff0c;最常用的相关系数有两种&#xff1a;皮尔逊相…

酷开科技丨酷开系统重塑家庭娱乐生态,开启家庭生活新体验

家庭是社会的“基本细胞”。每一个小家都是国家的组成部分&#xff0c;每一个家庭的幸福才会带来整个社会和国家的幸福安定。家庭的意义&#xff0c;是爱、是关心、是陪伴&#xff0c;是一生的牵绊。我们大部分的时间都是在家庭中度过的&#xff0c;与家人相聚的时候&#xff0…

一款适合医院内部内网文件传输工具,了解一下!

在数字化时代&#xff0c;医院的数据管理和文件传输变得极其关键。医院内部的文件传输工具不仅需要满足基本的传输需求&#xff0c;还要考虑安全性、隐私保护和易用性等重要方面。以下是医院内网文件传输工具应具备的关键要素&#xff1a; 安全性&#xff1a;由于医院数据包含患…

内容产品运营方案业务架构解析与实践探索

### 背景 在信息爆炸的时代背景下&#xff0c;内容产品运营成为各行各业竞争的重要环节。构建合理的内容产品运营方案业务架构&#xff0c;能够帮助企业更好地管理内容生产、推广和变现&#xff0c;提升品牌影响力和商业价值。 ### 业务架构设计 #### 1. 内容生产与管理 建立…

滤波电阻器:用于能源系统和工业的高精度解决方案

滤波电阻器用于防止能源系统中的电源反馈。铝厂或钢铁厂的大型感应冶炼厂对电源频率产生谐波。这些必须不惜一切代价远离电网。过滤器通常以 T 或 L 元件的形式用于此目的。中压电源输入端的吸收电路由电容和电感的串联连接组成&#xff0c;对谐波进行负载并衰减谐波。 为了避…

【二叉树】Leetcode 637. 二叉树的层平均值【简单】

二叉树的层平均值 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[3.00000,14.50000,11.00000] 解释&#xff1a…

【qt15】windeployqt 安装依赖

debug模式vs可以使用qt插件新建qt文件 D:\Qt15\5.15.2\msvc2019\bin\windeployqt.exe Warning: Cannot find Visual Studio installation directory, VCINSTALLDIR is not set.D:\Qt15\5.15.2\msvc2019\bin\windeployqt.exe .\filecopier.exeWindows PowerShell Copyright (C) …

推荐一个简单可靠的驰骋低代码组织结构设计,设计开发使用20年了

题目&#xff1a;推荐一个简单可靠的组织结构设计。 以下观点是驰骋低代码设计者的观念与主张&#xff0c;根据如下内容生成。 组织结构分为&#xff1a;单组织模式、集团组织模式、SAAS组织模式。组织结构包含&#xff0c;人员、部门、角色、人员部门的关系、人员部门角色的关…

什么是泛洪攻击?DDos攻击也是泛洪攻击的一种?

在数字化时代的浪潮中&#xff0c;网络安全已成为一场没有硝烟的战争。其中&#xff0c;泛洪攻击作为一种常见的网络攻击手段&#xff0c;对个人用户、企业乃至国家网络安全构成了严重威胁。本文将对泛洪攻击进行深入剖析&#xff0c;包括其定义、原理、类型、影响以及应对策略…

【Redis数据库】命令操作

文章目录 一、连接命令二、键命令 &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f495;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01; &#x1f495;希望您在这里可以感受到一份轻松愉快的氛围&#xff01; &#x1f495;这里不仅可以获得有…

ai聊天机器人app的分享!有4个热门的软件!

在科技日新月异的今天&#xff0c;AI聊天机器人已经不再是遥不可及的科幻概念&#xff0c;而是实实在在走进了我们的日常生活。无论是工作中的信息查询&#xff0c;还是生活中的闲聊解闷&#xff0c;这些智能助手都能为我们提供便捷、高效的服务。那么&#xff0c;市面上都有哪…

python系列29:压测工具locust

1. 介绍 使用pip进行安装&#xff0c;下面是个简单例子&#xff1a; from locust import HttpUser, taskclass HelloWorldUser(HttpUser):taskdef hello_world(self):self.client.get("/hello")self.client.get("/world")然后打开web页面&#xff1a; 点…

深度剖析可视化大屏的技术架构

在当今信息化时代&#xff0c;可视化大屏作为一种重要的信息展示方式&#xff0c;广泛应用于监控指挥中心、数据分析展示等领域。其技术架构对于保障大屏系统的稳定性和性能至关重要。本文将深入探讨可视化大屏的技术架构&#xff0c;包括硬件架构、软件架构和数据架构等方面&a…

电位器、金属触摸传感器、红外避障传感器、烟雾传感器、倾斜开关传感器 | 配合Arduino使用案例

电位器 电位器就是一个旋转按钮&#xff0c;可以读取到开关旋转的数值&#xff08;范围&#xff1a;0-1023&#xff09; /****** Arduino 接线 ***** VCC - 5v* GND - GND* OUT - A0***********************/int mainPin A0; // 接继电器的 IN 端口void setup() { Serial.be…

提示词工程基础:定义与重要性

目录 一、引言二、提示词工程的定义1. 概念明晰2. 技术框架3. 功能作用 三、提示词工程的重要性1. 核心作用强调2. 提升效率与降低成本3. 推动技术发展与创新 四、提示词工程的组成部分1. 提示词设计2. 模型训练与调整3. 效果评估与优化 五、实际应用示例1. 虚拟助手2. 自动新闻…

【Python数据分析--Numpy库】Python数据分析Numpy库学习笔记,Python数据分析教程,Python数据分析学习笔记(小白入门)

一&#xff0c;Numpy教程 给大家推荐一个很不错的笔记&#xff0c;个人长期学习过程中整理的 Python超详细的学习笔记共21W字点我获取 1-1 安装 1-1-1 使用已有的发行版本 对于许多用户&#xff0c;尤其是在 Windows 上&#xff0c;最简单的方法是下载以下的 Python 发行版…

了解一下Ubuntu Linux

1.3.1 什么是Ubuntu Ubuntu这个名字非常神奇&#xff0c;它取自非洲南部祖鲁语的ubuntu&#xff0c;是一个哲学名称&#xff0c;其意思为“人性”或者“我的存在是因为大家的存在”。对于中国人来说&#xff0c;一般称呼它为乌班图。 Ubuntu是在Debian的基础上开发出来的&am…

qt dragEnterEvent dragLeaveEvent dragMoveEvent dropEvent都不响应的问题解决方案。

环境&#xff1a;vs2019qt5.14.2 坑哦。让我搞了好久。各种不执行&#xff0c;最后发现,不用vs调制&#xff0c;直接运行exe就能接收拖拽了。 记录一下,感觉是qt的bug。上代码。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QText…

算法金 | 再见,PCA 主成分分析!

​大侠幸会&#xff0c;在下全网同名[算法金] 0 基础转 AI 上岸&#xff0c;多个算法赛 Top [日更万日&#xff0c;让更多人享受智能乐趣] 1. 概念&#xff1a;数据降维的数学方法 定义 主成分分析&#xff08;PCA&#xff09;是一种统计方法&#xff0c;通过正交变换将一组可…