【C++20新特性】ranges::sort()使用方法,优势,注意点

以下是关于 ranges::sort() 的详细说明:

1. ranges::sort() 的使用方法

ranges::sort()C++20 引入的基于范围(Ranges)的排序函数,其语法更简洁,支持直接操作容器或范围对象。

(1)基本用法

#include <vector>
#include <ranges>
#include <algorithm>int main() {std::vector<int> numbers = {3, 1, 4, 1, 5};std::ranges::sort(numbers); // 直接对容器排序return 0;
}

(2)逆序排序

通过传递 std::greater<> 实现降序:

std::ranges::sort(numbers, std::greater<>());

(3)自定义排序规则

使用 Lambda 表达式或自定义比较函数:

std::ranges::sort(numbers, [](int a, int b) {return a % 3 < b % 3; // 按模3的余数排序
});

2. 相比于传统 std::sort 的优势

(1) 更简洁的语法

传统 std::sort 需要手动指定迭代器范围:

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

ranges::sort 直接操作容器,省去迭代器:

std::ranges::sort(numbers); // 无需 begin/end 

(2) 支持范围概念(Concepts)

ranges::sort 在编译期通过概念(Concepts)检查参数合法性,错误提示更清晰。例如,若元素类型不支持比较,编译器会直接报错。

(3) 与范围库的无缝结合

可与其他范围适配器(如视图 views)结合使用,实现链式操作:

// 过滤偶数后排序
auto filtered = numbers | std::views::filter([](int x) { return x % 2 == 0; });
std::ranges::sort(filtered);

(4) 性能优化

对大型数据集可能有性能优化,因底层实现可能采用更高效的策略。

3. 使用注意点

(1) C++20 兼容性

需确保编译器支持 C++20 标准(如 GCC 10+、Clang 13+、MSVC 19.29+)。

(2) 元素类型需支持比较

元素类型必须定义 < 运算符或提供自定义比较函数。否则编译失败。

(3) 比较函数的严格弱序

自定义比较函数需满足严格弱序(Strict Weak Ordering),否则行为未定义。

(4) 视图的惰性计算

若对视图(如 views::filter 结果)调用 ranges::sort,需注意视图可能是惰性计算的,可能导致意外结果3。
总结

ranges::sort 通过简化语法、增强类型安全和优化性能,成为 C++20 中更现代的排序选择。在支持 C++20 的项目中优先使用,可提升代码可读性和健壮性。传统 std::sort 仍适用于旧代码或低版本编译器环境。

4. 实际分析

看灵神的代码的时候发现一个排序是这样写的:

vector<vector<int>> queries;
//...
ranges::sort(queries, {}, [](auto& q) { return q[0]; });

这段代码的作用是对二维向量 queries 按每行第一个元素(即 q)进行升序排序。以下是详细分析:


4.1 代码解析

ranges::sort(queries, {}, [](auto& q) { return q; });
  • 参数含义

    • queries:待排序的二维向量(vector<vector<int>>)。
    • {}:占位符,表示使用默认比较规则(std::less,即升序)。
    • [](auto& q) { return q; }:投影函数(Projection),指定排序依据为每行的第一个元素 q
  • 等效传统写法(使用 std::sort):

    std::sort(queries.begin(), queries.end(), [](const auto& a, const auto& b) {return a < b;
    });
    

4.2 优势:ranges::sort 的简洁性

  1. 直接操作容器:无需手动传递 begin/end 迭代器(传统写法需 queries.begin(), queries.end())。
  2. 投影函数:通过 [](auto& q) { return q; } 直接指定排序字段,避免了在比较函数中重复提取 ab,代码更简洁。
  3. 类型安全:C++20 的 ranges::sort 通过概念(Concepts)检查参数合法性,确保投影后的值可比较。

3. 注意点

  1. 子向量非空:必须确保每行子向量至少有一个元素,否则 q 会导致未定义行为(如越界访问)。
  2. 严格弱序:默认使用 std::less 升序排序,若需降序,需显式传递 std::greater{} 作为第二个参数:
    ranges::sort(queries, std::greater{}, [](auto& q) { return q; });
    
  3. 兼容性:需编译器支持 C++20(如 GCC 10+、Clang 13+)。

4. 与传统 std::sort 的对比

特性ranges::sort传统 std::sort
语法简洁性直接操作容器,无需迭代器需手动传递 begin/end 迭代器
投影函数支持,简化字段提取逻辑需在比较函数中显式提取字段
类型检查编译期概念检查,错误提示更友好运行时可能因类型错误崩溃

总结

这段代码利用 C++20 的 ranges::sort 对二维向量按首元素升序排序,通过投影函数简化了逻辑,是更现代的写法。注意确保子向量非空,并根据需求调整升/降序规则。在支持 C++20 的项目中推荐优先使用 ranges::sort

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

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

相关文章

深入理解设计模式之适配器模式

深入理解设计模式之适配器模式 1. 适配器模式概述 适配器模式(Adapter Pattern)是一种结构型设计模式&#xff0c;它允许将一个类的接口转换为客户端所期望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的类能够协同工作&#xff0c;扮演了"转换器&quo…

【数据结构 · 初阶】- 快速排序

目录 一. Hoare 版本 1. 单趟 2. 整体 3. 时间复杂度 4. 优化&#xff08;抢救一下&#xff09; 4.1 随机选 key 4.2 三数取中 二. 挖坑法 格式优化 三. 前后指针&#xff08;最好&#xff09; 四. 小区间优化 五. 改非递归 快速排序是 Hoare 提出的一种基于二叉树…

第2周 PINN核心技术揭秘: 如何用神经网络求解偏微分方程

1. PDEs与传统数值方法回顾 (Review of PDEs & Traditional Numerical Methods) 1.1 什么是偏微分方程 (Partial Differential Equations, PDEs)? 偏微分方程是描述自然界和工程领域中各种物理现象(如热量传播、流体流动、波的振动、电磁场分布等)的基本数学语言。 1.…

Neo4j(二) - 使用Cypher操作Neo4j

文章目录 前言一、Cypher简介二、数据库操作1. 创建数据库2. 查看数据库3. 删除数据库4. 切换数据库 三、节点、关系及属性操作1. 创建节点与关系1.1 语法1.2 示例 2. 查询数据2.1 语法2.2 示例 3. 更新数据3.1 语法3.2 示例 4. 删除节点与关系4.1 语法4.2 示例 5. 合并数据5.1…

RabbitMQ的Web管理页面给我看懵了,这都什么意思啊

文章目录 OverviewTotalsMessage RatesQueued Messages NodesChurn StatisticsPorts and ContextsExport DefinitionsImport Definitions ConnectionsChannelsExchangesQueuesAdmin他们之间的关联 在上一篇文章中我们讲到了如何在Windows中安装Rabbitmq&#xff0c; 小白也能搞…

安全基础与协议分析

5.1 Web安全基础 5.1.1 Web安全基础概览&#xff08;一、二&#xff09; Web安全的核心目标是保护Web应用及其数据免受攻击&#xff0c;涵盖以下关键领域&#xff1a; 攻击面&#xff1a; 前端漏洞&#xff08;XSS、CSRF&#xff09;。 后端漏洞&#xff08;SQL注入、RCE&a…

STM32项目实战:ADC采集

STM32F103C8T6的ADC配置。PB0对应的是ADC1的通道8。在标准库中&#xff0c;需要初始化ADC&#xff0c;设置通道&#xff0c;时钟&#xff0c;转换模式等。需要配置GPIOB的第0脚为模拟输入模式&#xff0c;然后配置ADC1的通道8&#xff0c;设置转换周期和触发方式。 接下来是I2C…

第十四章:数据治理之数据源:数据源的数据接入、业务属性梳理及监控

本章开始&#xff0c;将进入9大模块的介绍。第一个模块我们先介绍&#xff1a;数据源。数据源是整个数据中台数据的来源&#xff0c;是一个起点。更好的管理好数据源这个起点&#xff0c;是数据治理的一个好的开始。 在【数据&#xff1a;业务生数据&#xff0c;数据生“万物”…

【C/C++】多线程开发:wait、sleep、yield全解析

文章目录 多线程开发&#xff1a;wait、sleep、yield全解析1 What简要介绍详细介绍wait() — 条件等待&#xff08;用于线程同步&#xff09;sleep() — 睡觉&#xff0c;定时挂起yield() — 自愿让出 CPU 2 区别以及建议区别应用场景建议 3 三者协作使用示例 多线程开发&#…

阿里云CDN刷新预热--刷新URL

文章目录 一、全英文URL刷新预热二、掺杂中文的URL刷新预热2.1 对带中文URL进行编码2.2 预热刷新 三、CDN刷新-核心作用与价值3.1 核心作用3.2 核心价值3.3 典型使用场景 *最后我想说&#xff1a;请你不要相信我说的每一句话&#xff0c;这只是我的个人经验* 一、全英文URL刷新…

Oracle 19c DG备库报错ORA-00313、ORA-00312、ORA-27037

Oracle 19c DG备库报错ORA-00313、ORA-00312、ORA-27037 错误排查问题处理错误排查 DG同步完成后,DG Broker show database发现以下告警信息: Database Warning(s):ORA-16826: apply service state is inconsistent with the DelayMins propertyORA-16789: standby redo log…

开源与闭源之争:AI时代的创新博弈与未来抉择

在人工智能技术狂飙突进的今天&#xff0c;开源与闭源之争已不再局限于技术圈的讨论&#xff0c;而是演变为一场关乎技术伦理、商业格局乃至人类文明走向的深度博弈。当Meta的Llama 3开源模型下载量突破百万&#xff0c;当OpenAI的GPT-5继续加固技术壁垒&#xff0c;这场没有硝…

NIFI的处理器:JSLTTransformJSON 2.4.0

该处理器使用JSLT转换FlowFile JSON有效负载的格式。使用转换后的内容创建新的FlowFile&#xff0c;并将其路由到“成功”关系。如果JSLT转换失败&#xff0c;则将原始FlowFile路由到“失败”关系。 需要注意的是&#xff0c;编译JSLT转换可能相当昂贵。理想情况下&#xff0c…

MySQL 索引失效及其解决办法

一、前言 在数据库优化中,索引(Index)是一项至关重要的技术手段,可以显著提升查询性能。然而,在实际开发过程中,MySQL 索引并不总是如预期生效。本文将从原理出发,系统地介绍索引失效的常见场景及其解决方案,帮助开发者有效规避性能陷阱。 二、索引基础回顾 MySQL 支…

趋势触发策略

趋势触发策略(TS版)是一种基于TrendTriggerFactor(TTF)的交易策略,通过柱状图颜色变化指示市场趋势的强度,并根据TTF的穿越信号进行买卖操作。 TTF是通过计算买方力量和卖方力量的差值除以两者之和的一半再乘以100得到的。 当TTF大于100时,柱状图显示为绿色,表示市场…

DeepSeek-R1 模型现已在亚马逊云科技上推出

亚马逊云科技提供众多免费云产品&#xff0c;可以访问&#xff1a;亚马逊云科技 在刚刚过去的 Amazon re&#xff1a;Invent 期间&#xff0c;Amazon 首席执行官 Andy Jassy 分享了从 Amazon 自己在全公司开发近 1000 个生成式 AI 应用程序的经验中汲取的宝贵经验。从这种广泛…

中台项目-微前端qiankun-umimax

学习视频&#x1f50a; 基础&#xff1a; 黑马前端基于qiankun搭建微前端项目实战教程_哔哩哔哩_bilibili 路由、部署配置注意&#xff1a;qiankunvite微前端上线注意事项&#xff0c;base公共路径设置_哔哩哔哩_bilibili 微前端 什么是微前端&#xff1f; 微前端是将前端应…

【Java学习笔记】代码块

代码块 介绍&#xff1a;代码块又称为初始化块&#xff0c;属于类中的成员&#xff08;即是类的一部分&#xff09;&#xff0c;类似于方法&#xff0c;将逻辑语句封装在方法体中&#xff0c;通过{}包围起来 与类方法的不同点 无方法名 无返回类型 无参数 只有方法体&#…

spring boot 2.7集成旧的springfox-boot-starter swagger oas 3.0

旧版本目前已经不维护推荐使用 springdoc-openapi-ui&#xff0c;这里为了演示使用旧的最新依赖 <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version> </dep…

Linux按键驱动测试方式详细介绍

Linux按键驱动测试可采用以下分层方法&#xff1a; 基础事件检测 使用输入子系统调试工具&#xff1a; sudo apt install evtest # 安装事件测试工具 evtest # 选择对应设备编号触发按键后观察终端输出&#xff0c;正常情况应显示&#xff1a; Event:…