C++ 算法与 ranges:用 find_if、transform 写清数据处理意图

C++ 算法与 ranges:用 find_if、transform 写清数据处理意图

很多循环并不复杂,只是在寻找一个元素,或者把每个元素转换成另一种值。把这种意图交给标准算法,代码通常比手动维护下标更容易检查。

最低标准:C++20。本篇同时展示传统迭代器算法与 ranges 算法。

1. 查找符合条件的元素,再生成结果

cpp 复制代码
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

struct Item { std::string name; int price; };

int main() {
    std::vector<Item> items{{"pen", 3}, {"book", 12}, {"bag", 35}};
    auto found = std::find_if(items.begin(), items.end(),
                              [](const Item& x) { return x.price >= 10; });
    if (found != items.end()) std::cout << found->name << '\n';

    std::vector<int> doubled;
    std::ranges::transform(items, std::back_inserter(doubled),
                           [](const Item& x) { return x.price * 2; });
    for (int value : doubled) std::cout << value << ' ';
    std::cout << '\n';

    auto cheap = std::ranges::find_if(items,
        [](int price) { return price < 5; }, &Item::price);
    if (cheap != items.end()) std::cout << cheap->name << '\n';
}

输出依次为 book、6 24 70、pen。find_if 返回第一个满足条件的位置;找不到时返回结束迭代器,必须先判断再解引用。它不会把所有匹配项收集起来。

2. ranges 的投影让条件更专注

最后一次查找把 &Item::price 作为投影:算法先取得价格,再把价格交给条件函数。这样条件本身无需知道 Item 的其他字段。

ranges 版本通常可以直接接收容器,不必重复写 begin/end。不过"写法更短"不意味着生命周期问题消失。不要长期保存容器失效后的迭代器;对某些临时范围调用算法时,返回类型会使用 dangling 来阻止错误借用。

3. transform 不会自动扩大普通目标容器

若把空 vector 的 begin 作为输出位置,算法不会自动插入元素。应先 resize 到足够长度,或像示例一样使用 back_inserter。reserve 只预留容量,不会增加 size,不能替代 resize。

输入和输出的关系也要遵守算法约定:需要原地转换时,可以把输出起点设为输入起点;不要随意使用错位重叠区间。转换过程中也不应通过副作用改变正在遍历的容器结构。

4. 算法表达意图,普通循环表达流程

"找第一个""逐个转换""判断是否全部满足"很适合算法;如果每一步都有复杂状态迁移、多个退出条件和错误恢复,清晰的普通循环可能更合适。

把判断函数写成无意外副作用的小函数,避免假设 transform 的调用顺序可以承担业务流程。最终目标不是消灭 for,而是让读者一眼看出代码在做什么。

进一步阅读:Microsoft 标准算法参考。

相关推荐
白杨尚青7 小时前
C++进阶篇(二):多态——虚函数、重写、虚函数表与三个经典坑(附完整代码仓库)
开发语言·c++·多态·虚函数·重写·动态绑定
syagain_zsx7 小时前
spdlog实战:日志分级、滚动与性能调优
linux·c++·日志库·二次开发日志库
zyl76521 小时前
FlashAttention 详解:从 GPU 硬件、普通 Attention 到分块计算与 Online Softmax
算法
爱读书的小胖1 天前
LeetCode 122:买卖股票的最佳时机 II(C)解题分析
算法
结局无敌1 天前
React Native for OpenHarmony 实战:三方库 react-native-modal-dialog 的鸿蒙化适配指南
深度学习·算法·react native·react.js·harmonyos
WJ.Polar1 天前
Java封装、继承、多态
java·开发语言
摇滚侠1 天前
Java 中如何表示负数,有符号和无符号的区别,补码的计算规则,char byte short int long 的范围
java·开发语言
OPEN-F1 天前
ROS2系列教程:上位机建图与导航(原理综合)
算法·机器人
weixin_307779131 天前
C++代码实现MATLAB中的fitrtree函数功能
开发语言·c++·算法·matlab
AI wins1 天前
c++新增頭文件
c++