C++ 20新特性之Ranges

💡 如果想阅读最新的文章,或者有技术问题需要交流和沟通,可搜索并关注微信公众号“希望睿智”。

为什么要引入Ranges

        在C++ 20之前,我们处理容器和迭代器时,通常需要使用一系列的算法和复杂的迭代器操作。这不仅繁琐,而且很容易出错,尤其是对于复杂的算法组合。C++ 20引入Ranges的原因主要是为了提高标准库的表达力、效率和代码的可读性,以及简化序列操作的复杂度。

        任何可以被迭代的对象都可以视为Ranges,包括标准库容器(比如:vector、list、map等)、数组,甚至是由函数生成的连续或非连续元素序列。Ranges提供了一组函数和操作符,让我们能够以更加函数式的方式处理容器中的数据。这些函数和操作符通常与现有的STL算法具有相同的功能,但它们更简洁,也更易于使用。

Ranges视图

        View是Ranges的核心,相当于一个透镜,通过它可以观察Ranges的不同视图。视图是一个对数据的非拥有、可能懒加载的引用,它不会复制或修改原始数据,而是提供了一种方式来查看或处理这些数据。这使得我们可以在不修改原始数据的情况下,对数据进行过滤、映射、切片等各种复杂的操作。

        在下面的示例代码中,我们使用views::filter来过滤出一个整型容器中的偶数,得到了视图viewEven。最后,我们使用ranges::for_each来遍历视图viewEven进行输出。

#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
using namespace std;int main()
{vector<int> vctNum = {1, 2, 3, 4, 5};auto viewEven = vctNum | views::filter([](int n) { return n % 2 == 0; });// 输出: 2 4ranges::for_each(viewEven, [](int n) { cout << n << ' '; });return 0;
}

Ranges适配器

        Ranges适配器负责接收一个输入Range(或多个输入Ranges),并根据适配器定义的规则转换或处理这些输入,最终产生一个新的Range。这个过程通常是懒惰执行的,意味着数据仅在实际访问时才会被处理。常见的适配器有如下几种。

        转换适配器(Transform Adapter):比如ranges::view::transform,它接受一个函数或Lambda,对输入Range中的每个元素应用该函数,并生成一个新元素。

        过滤适配器(Filter Adapter):比如ranges::view::filter,它根据提供的谓词筛选出符合条件的元素,丢弃不符合条件的元素。

        取前N个元素适配器(Take Adapter):比如ranges::view::take,仅取Range的前N个元素,这对于处理有限制的数据流非常有用。

        丢弃前N个元素适配器(Drop Adapter):比如ranges::view::drop,丢弃Range的前N个元素,然后返回剩余的元素。

        合并适配器(Concatenate Adapter):比如ranges::view::join,用于将一系列Range(通常为Range的Range)连接成一个单一的Range。

        切片适配器(Slicing Adapter):比如ranges::view::slice,可以取出Range的一个子区间,类似于数组的切片操作。

        在下面的示例代码中,我们使用转换适配器将原始的vctNum转换成了一个视图,这个视图中每个元素的值为vctNum中每个元素的平方。最后,我们使用ranges::for_each来遍历视图viewSquared进行输出。注意:views::transform并不会修改原始的vctNum,而是产生了一个新的Range视图。

#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
using namespace std;int main()
{vector<int> vctNum = {1, 2, 3, 4, 5};auto viewSquared = vctNum | views::transform([](int n) { return n * n; });// 输出: 1 4 9 16 25ranges::for_each(viewSquared, [](int n) { cout << n << ' '; });return 0;
}

Ranges算法

        Ranges还提供了一组与STL算法类似的算法,这些算法可以直接在Range上操作,而无需显式地使用繁琐的迭代器。在下面的示例代码中,我们使用std::ranges::find来在vctNum中查找一个元素。

#include <iostream>
#include <vector>
#include <ranges>
#include <format>
using namespace std;int main()
{vector<int> vctNum = {1, 2, 3, 4, 5};auto it = ranges::find(vctNum, 2);if (it != vctNum.end()){cout << format("found {}", *it) << endl;}else{cout << "not found" << endl;}return 0;
}

管道操作符

        管道操作符,也就是“|”符号,是C++ 20中一个重载过的操作符。在Ranges库中,它用于连接一系列的操作,形成一个数据处理的管道。这意味着,数据可以从一个操作流向下一个操作,每个环节只关注处理数据,而不需要关心数据的来源和去向。当我们将numbers | ranges::view::...这样的表达式放在一起时,意味着我们正在创建一个处理numbers集合的管道,其中...代表具体的View操作。

        在下面的示例代码中,我们首先过滤出偶数,然后计算它们的平方,这展示了ranges的简洁性和表达力。通过这样的管道表达式,C++程序员能够以一种声明性的方式写出高效且易于理解的代码,特别适合进行数据处理和分析任务。

#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
using namespace std;int main()
{vector<int> vctNum = {1, 2, 3, 4, 5, 6};auto viewResult = vctNum | views::filter([](int x) { return x % 2 == 0; }) | views::transform([](int x) { return x * x; });// 输出:4 16 36ranges::for_each(viewResult, [](int x) { cout << x << " "; });return 0;
}

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

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

相关文章

java aio nio区别

Java AIO&#xff08;Asynchronous I/O&#xff09;和NIO&#xff08;Non-blocking I/O&#xff09;在并发模型、API和适用场景等方面有所不同。具体分析如下&#xff1a; 并发模型 AIO&#xff1a;AIO提供了异步非阻塞的IO操作&#xff0c;通过回调函数来通知IO操作的完成。在…

栈----7-9 括号匹配

给定一串字符&#xff0c;不超过100个字符&#xff0c;可能包括括号、数字、字母、标点符号、空格&#xff0c;编程检查这一串字符中的( ) ,[ ],{ }是否匹配。 输入格式: 输入在一行中给出一行字符串&#xff0c;不超过100个字符&#xff0c;可能包括括号、数字、字母、标点符…

量化投资分析平台 迅投 QMT(六)资产定价绕不过去的BSM模型

量化投资分析平台 迅投 QMT [迅投 QMT](https://www.xuntou.net/?user_code7NYs7O)我目前在使用什么是BSM模型CQF课程介绍模型的五个重要的假设模型公式 我们为啥要学&#xff08;知道&#xff09;这玩意儿呢&#xff1f;隐含波动率&#xff08;Implied Volatility&#xff09…

初阶 《函数》 4. 函数的调用

4. 函数的调用 4.1 传值调用 函数的形参和实参分别占有不同内存块&#xff0c;对形参的修改不会影响实参 4.2 传址调用 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式 这种传参方式可以让函数和函数外边的变量建立起真正的联系&#xff0c;也就是…

Bat脚本专栏目录及索引

文章目录 注释关闭回显和打印pauseerrorlevel 判断刚才的命令是否执行成功%value% 和 !value!的区别脚本名或路径有中文if条件判断语句for 循环语句set 变量设置findstr 搜索指令tasklist 进程列表指令文件操作时间延迟简单应用 注释 REM:: 关闭回显和打印 &#xff1a;字符…

大数据领域的workload是什么意思?

什么是workload&#xff1f; 在大数据领域&#xff0c;"workload"指的是需要处理的数据集和对其执行的操作的组合。它描述了大数据系统需要执行的任务的类型和规模。 我们可以从以下几个维度来理解大数据领域的 workload&#xff1a; 数据的特征: 数据量 需要处…

Linux下创建软raid(磁盘阵列)

raid &#xff0d;&#xff0d;磁盘阵列 RAID分为软RAID和硬RAID 如果cpu比较空闲&#xff0c;并且I/O比较慢的话&#xff0c;那么就比较适合使用软RAID 基本级别 0 1 5 0级别&#xff1a; 至少有两块硬盘&#xff0c;条带化&#xff0c;即把磁盘分散开&#xff0c; 写性能 …

sam_out 脱发预测

解释 这段代码是一个用于预测掉发问题的GPT模型的训练脚本。代码首先读取了一个包含预测特征的csv数据文件&#xff0c;并将特征进行编码。然后将数据集分成训练集和测试集。接下来定义了模型的结构&#xff0c;优化器和损失函数。然后进行多轮训练&#xff0c;每一轮都使用批…

堆和栈(heap and stack)

1、堆&#xff1a;一块内存空间&#xff0c;可以从中分配一个小buffer&#xff0c;用完后再把它放回去。 2、栈&#xff1a;也是一块内存空间&#xff0c;cpu的sp寄存器指向它&#xff0c;它可以用于函数调用、局部变量、多任务系统里保存现场。 PUSH [r3-r6,lr]; #将r3到r6寄…

C++之pair总结及其在点云数据存储中举例

1、前言 pair是将2个数据组合成一组数据&#xff0c;当需要这样的需求时就可以使用pair。如当一个函数需要返回2个数据的时候&#xff0c;可以选择pair。 pair的实现是一个结构体&#xff0c;主要的两个成员变量是first、second 因为是使用struct不是class&#xff0c;所以可以…

26.多边形的判定

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/499 题目描述 给定 𝑛n 个整数 𝑎1,𝑎…

base上海,数据科学,数据挖掘,数据分析等岗位求收留

裁员了&#xff0c;base上海&#xff0c;数据科学&#xff0c;数据挖掘&#xff0c;数据分析等岗位&#xff0c;期望30k~40k&#xff0c;求推荐求收留 1&#xff0c;6年数据算法工作&#xff0c;做过指标体系搭建&#xff0c;用户画像&#xff0c;货品定价&#xff0c;社区分析…

Nacos注册中心和配置中心

1 nacos简介 1.1nacos介绍 Nacos是阿里的一个开源产品&#xff0c;它是针对微服务架构中的服务发现、配置管理、服务治理的综合型解决方案。是微服务的注册中心和配置中心&#xff0c;相当于springcloudEureka和springconfig的集合。 Nacos 致力于帮助您发现、配置和管理微服务…

使用Leaflet-canvas-label进行个性化标注实践详解

目录 前言 一、leaflet-canvas-label属性 1、地图展示属性 2、Canvas文本标注属性 3、事件列表 二、属性设置实战 1、标注放大比例 2、字体颜色和方向偏移 3、标注文字透明色设置 4、标注显示层级 三、事件绑定 1、颜色改变 2、事件绑定解析 3、标记初始化的一个小…

28.找零

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/744 题目描述 有一台自动售票机,每张票卖 …

一文详解大模型微调全流程

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学. 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总合集&…

【大学物理】波动光学:光的衍射

23.2 单缝的夫琅禾费衍射_哔哩哔哩_bilibili 1 光的衍射和惠更斯-菲涅尔原理 干涉vs衍射&#xff1a;干涉研究的是两个分立的子光源&#xff0c;衍射研究的是连续的子光源。 两位科学家用分解的思想&#xff0c;一个解决了方向一个解决了光强。 2 单缝的夫琅禾费衍射 夫琅禾…

【JAVASE】java语法(成员变量与局部变量的区别、赋值运算符中的易错点)

一&#xff1a;成员变量与局部变量的区别 区别 成员变量 局部变量 类中位置不同 …

MySQL之查询性能优化(十四)

查询性能优化 使用用户自定义变量 优化排名语句 使用用户自定义变量的一个特性是你可以在给一个变量赋值的同时使用这个变量&#xff0c;换句话说&#xff0c;用户自定义变量的赋值具有"左值"特性。下面的例子展示了如何使用变量来实现一个类似"行号(row num…

【第14章】SpringBoot实战篇之多环境配置

文章目录 前言一、通用配置文件1. 定义2. 使用2.1 application.yml2.2 启动类 3. 测试 二、多环境配置文件1.定义1.1 application-local.yml1.2 application-dev.yml1.3 application-test.yml1.4 application-prod.yml 2.使用2.1 application.yml2.2 启动类 3.测试 三、多环境配…