当年写 STL 算法。
你得学两样东西。
迭代器。
还有“怎么把迭代器传对”。
很多人不是输在算法。
是输在接口太绕。
当年:sort 一个结构体数组,得写一坨比较器
你有一组记录。
按分数排序。
struct User {
int id;
int score;
};
在 C++20 之前。
你大概率会这么写。
#include <algorithm>
#include <vector>
std::sort(users.begin(), users.end(),
[](const User& a, const User& b) {
return a.score < b.score;
});
这段没毛病。
但你会发现。
你写的不是“按 score 排序”。
你写的是一段样板。
线上啪一下:比较器写错了,日志看不出来
这种 bug 很现实。
你把 < 写成 >。
或者你比较了 id。
上线后。
排行榜顺序怪怪的。
你盯着那段 lambda。
看了三遍。
才发现你比较字段写错了。
C++20:ranges::sort + projection
ranges 算法支持一个东西。
projection。
你可以把它理解成。
“先从元素里取出要比较的键”。
#include <algorithm>
#include <ranges>
std::ranges::sort(users, {}, &User::score);
这里第二个参数 {}。
是比较器。
留空就是默认的 std::ranges::less。
第三个参数 &User::score。
就是 projection。
意思是。
“比较前先取 score”。
你刚学 C++ 可能会卡:&User::score 是啥
它叫“成员指针”。
你可以先粗暴理解成。
“告诉算法:字段在哪里”。
ranges 会用它。
从 User 里拿到 score。
然后再做比较。
find 也一样:少传迭代器,多传容器
老写法是这样。
#include <algorithm>
auto it = std::find_if(users.begin(), users.end(),
[](const User& u) { return u.id == 7; });
ranges 写法更像句子。
#include <algorithm>
#include <ranges>
auto it = std::ranges::find(users, 7, &User::id);
它在说。
“在 users 里找 id 为 7 的元素”。
关键结论
ranges 算法没变。
变的是。
你可以把“按哪个字段”当成参数。
而不是硬塞进一段 lambda。
小结
你写比较器的时候。
其实是在写意图。
projection 让你把意图写得更直接。
而且更不容易写错。