以前写 C。
你要处理一堆数据。
就写 for。
一个不够。
就再来一个。
再不够。
就把中间结果存起来。
代码能跑。
但读起来像厨房台面。
全是盆。
全是碗。
当年:STL 给了算法,但没给“流水线”
STL 早就有 std::sort。
有 std::find_if。
有 std::transform。
它们都挺好。
问题在于。
你想把它们串起来的时候。
你会开始不停地造容器。
不停地写迭代器。
线上啪一下:我只想从日志里挑出几条
假设你写了个小工具。
读一堆数字。
代表一堆错误码。
你只想。
挑出偶数。
每个乘 10。
取前 3 个。
拼成一个字符串给报警系统。
老写法往往长这样。
#include <string>
#include <vector>
std::vector<int> tmp;
for (int x : codes) {
if (x % 2 == 0) tmp.push_back(x * 10);
if (tmp.size() == 3) break;
}
它能用。
但它很像“过程记录”。
你得盯着每一行。
才能还原意图。
Ranges 的想法:把意图写成一条管道
C++20 说。
别急着落地成容器。
先把操作连起来。
需要结果的时候。
再把它“倒出来”。
#include <ranges>
#include <vector>
auto r = codes
| std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * 10; })
| std::views::take(3);
这段看起来像流水线。
先过滤。
再变换。
再截断。
而且顺序就是你的意图顺序。
你刚学 C++ 会皱眉的三个词
range
你可以把它先理解成。
“能遍历的一段东西”。
有 begin/end。
就差不多了。
view
view 更像“视图”。
它不急着生成新容器。
它只是描述一件事。
“我打算怎么看这份数据”。
惰性求值
上面那条管道。
不会立刻跑。
你不去遍历它。
它就不会做事。
这点很重要。
因为它让你少造临时对象。
也让你能把操作串得很长。
把结果倒出来:真正开始跑
你要用它。
就遍历它。
#include <string>
std::string out;
for (int x : r) {
if (!out.empty()) out += ",";
out += std::to_string(x);
}
遍历发生的那一刻。
filter/transform/take 才开始工作。
关键结论
Ranges 不会替你发明新算法。
它只是让你。
把“怎么处理数据”写得更像一句话。
小结
你以前写一堆 for。
是在写步骤。
Ranges 让你先写意图。
再让循环去执行。
当你半夜回来看代码。
它会更像自己在解释自己。