C++20 范围(Range):简化集合操作

C++20 范围:简化集合操作

  • 一、范围(Range)的目的
  • 二、在模板函数中使用范围概念
  • 三、投影
  • 四、视图
  • 五、结论

一、范围(Range)的目的

在 C++20 中,范围概念要求一个对象同时拥有迭代器和结束哨兵。这在标准集合的上下文中非常有用,特别是在开发针对集合的操作算法(例如模板函数)时。

假设有一个想要排序的值向量:

std::vector<int> values = {10, 20, 15, 35, 5};

可以使用 std::sort() 函数来排序:

std::sort(values.begin(), values.end());

注意,需要传递两个参数,分别是迭代器 values.begin()values.end()。如果能够直接将集合传递给排序函数,那就太好了。

在 C++20 中,std::ranges 命名空间使得这成为可能。因此,可以这样写:

std::ranges::sort(values);

为了实现这一点,ranges::sort() 函数需要使用模板约束,即:

  • 对象拥有一个返回迭代器的 begin() 方法
  • 对象拥有一个返回结束哨兵的 end() 方法

只要满足这两个要求,算法就能正常工作,而实现无需知道实际集合是vectorlist还是其他类型。

这些要求由 std::ranges::range concept形式化,该概念在 C++20 范围库中定义。

二、在模板函数中使用范围概念

如何使用范围概念来开发自己的算法:

#include <ranges>template <typename T> 
requires std::ranges::range<T>
void mySort(T x)
{// 为了演示,我们只是包装了旧的 STL 算法。std::sort(x.begin(), x.end());
}

然后,只需用一个参数调用 mySort() 函数:

mySort(values);

三、投影

对对象数组进行排序的问题。以下表示学生考试成绩的类:

class Result
{
public:int studentId;int score;
};

不能简单地调用 std::ranges::sort(),因为 Result 类没有定义 < 运算符。此外,需要告诉排序函数这里是想按 studentId 还是按 score 排序。

新的 std::ranges 库允许指定一个自定义比较器作为可选的第二个参数,例如:

std::ranges::sort(results,[](const Result& x, const Result& y){return x.score < y.score;});

在 C++20 中,可以通过利用 std::ranges::sort() 函数支持投影的事实来进一步简化。这允许指定一个一元函数,用来转换集合中的每个元素:

std::ranges::sort(results, std::ranges::less{},[](const Result& x){return x.score;});

这里,第三个参数是投影,它将每个 Result 对象转换为其整数 score 值。

需要在第二个参数中提供一个比较器,但由于我们已将元素“投影”到整数,因此可以使用内置的 std::ranges::less 比较器。

更棒的是,由于投影的默认模板类型是 std::ranges::less,可以为第三个参数写 {} 来表示想要使用默认构造函数。因此,代码变为:

std::ranges::sort(results, {},[](const Result& x){return x.score;});

可以使用“指向成员的指针”语法进一步简化:

std::ranges::sort(results, {},&Result::score);

四、视图

视图是范围适配器。因此,可以过滤范围中的元素,或对每个元素应用转换。所有这一切都在不需要分配任何新对象或复制集合的情况下完成。视图的结果本身就是一个范围,因此视图可以链接在一起,或随后传递到范围库中的任何算法。

例如,如果有一个向量 vec,可以删除范围中的第一个元素:

std::views::drop(vec, 1);

可以反转元素:

std::views::reverse(vec);

可以使用管道符号将范围适配器链接在一起:

vec | std::views::reverse | std::views::drop(1);

可以使用过滤器来选择仅包含偶数元素的范围:

vec | std::views::filter([](auto i) { return 0 == i % 2; });

视图的强大之处在于它们允许延迟求值。

五、结论

范围为处理集合提供了急需的功能。它们为语法和可读性带来了重大改进。范围是 C++20 概念实际应用的绝佳示例。
在这里插入图片描述

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

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

相关文章

YOLOv5改进(五)-- 轻量化模型MobileNetv3

文章目录 1、MobileNetV3论文2、代码实现2.1、MobileNetV3-small2.2、MobileNetV3-large 3、运行效果4、目标检测系列文章 1、MobileNetV3论文 Searching for MobileNetV3论文 MobileNetV3代码 MobileNetV3 是 Google 提出的一种轻量级神经网络结构&#xff0c;旨在在移动设备上…

官网上线,一款令人惊艳的文本转语音模型:ChatTTS

近日&#xff0c;一个名为 ChatTTS 文本转语音模型的项目在github上横空出世&#xff0c;一经推出便引发极大关注&#xff0c;短短四天时间&#xff0c;已经狂揽了14.2k的Start量。 ChatTTS是一款专为对话场景设计的支持中英文的文本转语音&#xff08;TTS&#xff09;模型&…

未来已来:Spring Boot引领数据库智能化革命

深入探讨了Spring Boot如何与现代数据库技术相结合&#xff0c;预测并塑造未来的数据访问趋势。本书不仅涵盖了Spring Data JPA的使用技巧&#xff0c;还介绍了云原生数据库的概念&#xff0c;微服务架构下的数据访问策略&#xff0c;以及AI在数据访问层的创新应用。旨在帮助开…

XFeat:速度精度远超superpoint的轻量级图像匹配算法

代码地址&#xff1a;https://github.com/verlab/accelerated_features?tabreadme-ov-file 论文地址&#xff1a;2404.19174 (arxiv.org) XFeat (Accelerated Features)重新审视了卷积神经网络中用于检测、提取和匹配局部特征的基本设计选择。该模型满足了对适用于资源有限设备…

在table中获取每一行scope的值

目的 当前有一份如下数据需要展示在表格中&#xff0c;表格的页面元素套了一个折叠面板&#xff0c;需要循环page_elements中的数据展示出来 错误实践 将template放在了折叠面板中&#xff0c;获取到的scope是空数组 <el-table-column label"页面元素" show-o…

【并发程序设计】15.信号灯(信号量)

15.信号灯(信号量) Linux中的信号灯即信号量是一种用于进程间同步或互斥的机制&#xff0c;它主要用于控制对共享资源的访问。 在Linux系统中&#xff0c;信号灯作为一种进程间通信&#xff08;IPC&#xff09;的方式&#xff0c;与其他如管道、FIFO或共享内存等IPC方式不同&…

分析和设计算法

目录 前言 循环不变式 n位二进制整数相加问题 RAM模型 使用RAM模型分析 代码的最坏情况和平均情况分析 插入排序最坏情况分析 插入排序平均情况分析 设计算法 分治法 总结 前言 循环迭代&#xff0c;分析算法和设计算法作为算法中的三个重要的角色&#xff0c;下面…

Java——二进制原码、反码和补码

一、简要介绍 原码、反码和补码只是三种二进制不同的表示形式&#xff0c;每个二进制数都有这三个形式。 1、原码 原码是将一个数的符号位和数值位分别表示的方法。 最高位为符号位&#xff0c;0表示正&#xff0c;1表示负&#xff0c;其余位表示数值的绝对值。 例如&…

如何解决游戏行业DDOS攻击问题

随着网络游戏行业的迅速发展&#xff0c;网络游戏问题也不可忽视&#xff0c;特别是目前网络攻击频发&#xff0c;DDoS攻击的简单化以及普及化&#xff0c;对游戏来说存在非常大的安全威胁。 随着受攻击对象的范围在不断地拓展&#xff0c;网络游戏这种这种新型并且有着丰厚利…

Scala编程基础3 数组、映射、元组、集合

Scala编程基础3 数组、映射、元组、集合 小白的Scala学习笔记 2024/5/23 14:20 文章目录 Scala编程基础3 数组、映射、元组、集合apply方法数组yield 数组的一些方法映射元组数据类型转换求和示例拉链集合flatMap方法 SetHashMap apply方法 可以new&#xff0c;也可以不new&am…

flink Jobmanager metaspace oom 分析

文章目录 现象作业背景分析现象分析类卸载条件MAT 分析 解决办法flink 官方提示 现象 通过flink 页面提交程序&#xff0c;多次提交后&#xff0c;jobmanager 报metaspace oom 作业背景 用户代码是flink 代码Spring nacos 分析 现象分析 从现象来看肯定是因为有的类没有被…

Linux系统-前台任务组,后台任务组

文章目录 前台进程后台进程新命令jobsfg 【后台进程组序号】ctrlz组合键信号 和 bg命令ctrlz组合键信号bg 【后台进程组序号】 session会话此时我们关闭本次的会话&#xff0c;我们的后台进程是否也会退出呢&#xff1f; 总结 前台进程 在我们远程登录Linux服务器后&#xff0…

创建__init__()方法

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在创建类后&#xff0c;可以手动创建一个__init__()方法。该方法是一个特殊的方法&#xff0c;类似Java语言中的构造方法。每当创建一个类的新实例时…

【AI界的狼人杀】人工智能“反图灵测试”实验

5月28日&#xff0c; AI Power Users、Unity 独立开发者&#xff1a;Tore Knabe 在其社交平台发布了一则名为《Reverse Turing Test Experiment with AIs》的视频&#xff0c;立马引发了热议。 视频中共出现了五位主要角色&#xff0c;“他们”分别是&#xff1a;亚里士多德&am…

961操作系统知识总结

部分图片可能无法显示&#xff0c;参考这里&#xff1a;https://zhuanlan.zhihu.com/p/701247894 961操作系统知识总结 一 操作系统概述 1. 操作系统的基本概念 重要操作系统类型&#xff1a;批处理操作系统(批量处理作业&#xff0c;单道批处理/多道批处理系统&#xff0c;用…

RabbitMQ-直连交换机(direct)使用方法

RabbitMQ-默认读、写方式介绍 RabbitMQ-发布/订阅模式 目录 1、概述 2、直连交换机 3、多重绑定 4、具体代码实现 4.1 生产者部分 4.2 消费者部分 5、运行代码 6、总结 1、概述 直连交换机&#xff0c;可以实现类似路由的功能&#xff0c;消息从交换机发送到哪个队列…

夜天之书 #98 Rust 程序库生态合作的例子

近期主要时间都在适应产品市场&#xff08;Product Marketing&#xff09;的新角色&#xff0c;不少想法还在酝酿和斟酌当中&#xff0c;于是文章输出没有太多时间来推敲和选题&#xff0c;只能保持每月发布相关的进展或一些零碎的思考。或许我可以恢复最早的模式&#xff0c;多…

YOLOv8改进(一)-- 轻量化模型ShuffleNetV2

文章目录 1、前言2、ShuffleNetV2代码实现2.1、创建ShuffleNet类2.2、修改tasks.py2.3、创建shufflenetv2.yaml文件2.4、跑通示例 3、碰到的问题4、目标检测系列文章 1、前言 移动端设备也需要既准确又快的小模型。为了满足这些需求&#xff0c;一些轻量级的CNN网络如MobileNe…

十_信号4-SIGCHLD信号

SIGCHLD信号 在学习进程控制的时候&#xff0c;使用wait和waitpid系统调用何以回收僵尸进程&#xff0c;父进程可以阻塞等待&#xff0c;也可以非阻塞等待&#xff0c;采用轮询的方式不停查询子进程是否退出。 采用阻塞式等待&#xff0c;父进程就被阻塞了&#xff0c;什么都干…

力扣83. 删除排序链表中的重复元素

Problem: 83. 删除排序链表中的重复元素 文章目录 题目描述思路复杂度Code 题目描述 思路 1.定义快慢指针fast、slow均指向head&#xff1b; 2.每次fast后移一位&#xff0c;当fast和slow指向的节点值不一样时&#xff0c;将slow.next指向fast同时使slow指向fast&#xff1b; 3…