0

0

如何用c++20的Ranges库简化算法操作? (代码实例)

尼克

尼克

发布时间:2026-01-09 14:27:44

|

905人浏览过

|

来源于php中文网

原创

std::ranges::sort(v)更安全清晰,直接传容器;视图组合filter/transform惰性高效;erase_if一步删除符合条件元素。

如何用c++20的ranges库简化算法操作? (代码实例)

std::ranges::sort 替代 std::sort,直接传容器而非迭代器

传统 std::sort 必须传入 begin()end() 迭代器,容易写错边界或搞混顺序;std::ranges::sort 接收整个范围(如 std::vectorstd::array),语义更清晰,也自动适配自定义范围。

常见错误:混用旧式迭代器和 ranges 算法,比如对 std::vector 调用 std::ranges::sort(v.begin(), v.end()) —— 这会退化为传统行为,失去 ranges 的优势,且可能因迭代器类型不匹配编译失败。

  • 正确写法:直接传容器对象,std::ranges::sort(v)
  • 支持自定义比较:std::ranges::sort(v, std::greater{})
  • 仅对子范围排序:用 std::ranges::subrange 或切片视图,例如 std::ranges::sort(v | std::views::take(5))(注意:这会排序前 5 个元素的副本,需用 std::views::take + std::ranges::sort 配合可写视图,实际中更推荐 std::ranges::sort(std::ranges::subrange(v.begin(), v.begin() + 5))
std::vector v = {3, 1, 4, 1, 5};
std::ranges::sort(v); // ✅ 直接、安全、可读
// v 变为 {1, 1, 3, 4, 5}

std::views::filterstd::views::transform 替代手写循环

传统方式要开新容器、遍历、条件判断、push_back……容易漏 reserve、误用 ===、索引越界。Ranges 视图是惰性求值的,组合起来不产生中间容器,内存友好,逻辑也更接近自然语言。

关键点:视图对象本身不拥有数据,不能脱离原容器生命周期使用;一旦原容器被移动或销毁,再访问视图会 UB。

立即学习C++免费学习笔记(深入)”;

Speech Studio
Speech Studio

微软语音服务,提供语音到文本、文本到语音和语音翻译功能。

下载
  • filter 接收一元谓词,返回满足条件的元素引用
  • transform 接收一元函数,返回转换后的新值(注意:若返回临时对象,需确保生命周期足够长)
  • 链式调用顺序即执行顺序:v | filter(...) | transform(...) 先过滤再转换
  • 要落地为容器,必须显式构造,例如 std::vector(v | std::views::filter(...) | std::views::transform(...))
std::vector v = {1, 2, 3, 4, 5, 6};
auto evens_squared = v 
    | std::views::filter([](int x) { return x % 2 == 0; })
    | std::views::transform([](int x) { return x * x; });

std::vector result(evens_squared.begin(), evens_squared.end()); // result 为 {4, 16, 36}

std::ranges::find_if + std::ranges::erase 安全删除满足条件的元素

旧式 remove_if + erase(erase–remove 惯用法)易出错:忘记 erase、迭代器失效、对 list 等非连续容器效率低。C++20 提供 std::ranges::erase(针对容器)和 std::ranges::erase_if(直接按条件删),语义明确、一步到位。

注意:std::ranges::erase_if 是容器专属算法,只接受容器(如 std::vectorstd::deque),不接受任意范围(如视图)。若你手头是个视图,得先确认它背后是否可修改且支持擦除。

  • std::ranges::erase_if(v, [](int x) { return x 删除所有负数
  • 返回值是被删元素个数,可用于断言或日志
  • std::vector,内部仍做移动,但接口屏蔽了细节;对 std::list,是真正的 O(n) 删除
std::vector v = {−2, 3, −1, 7, 0, −5};
auto n = std::ranges::erase_if(v, [](int x) { return x < 0; });
// v 变为 {3, 7, 0},n == 3

组合视图时小心求值时机和临时对象生命周期

这是最常被忽略的坑:视图是轻量级对象,但其内部可能绑定临时容器或 lambda 捕获。一旦绑定源离开作用域,继续使用视图就是悬垂引用。

典型错误场景:函数返回一个由局部容器生成的视图、在 lambda 中捕获局部变量后用于 transform、把 std::views::iota 和临时 vector 组合后存为成员变量。

  • 避免返回视图:改用返回 std::vector 或接收输出迭代器
  • lambda 捕获尽量用值捕获([x]),不用引用([&x])除非你能保证 x 生命周期覆盖视图使用期
  • 调试技巧:对怀疑悬垂的视图,加一句 std::ranges::size(view) 测试——若崩溃或返回异常大值,大概率是生命周期问题
// ❌ 危险:view 绑定到局部 vector,函数返回后失效
auto get_even_view() {
    std::vector local = {1, 2, 3, 4};
    return local | std::views::filter([](int x) { return x % 2 == 0; });
}

// ✅ 安全:立即物化为 vector auto get_even_vec() { std::vector local = {1, 2, 3, 4}; return std::vector(local | std::views::filter([](int x) { return x % 2 == 0; })); }

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

383

2023.09.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

532

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

51

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

202

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

189

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

40

2026.01.05

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

3

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 6.3万人学习

C 教程
C 教程

共75课时 | 3.9万人学习

C++教程
C++教程

共115课时 | 11.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号