1. 为什么需要自定义投影函数
在C++20引入ranges之前,我们经常需要写这样的代码来对自定义结构体进行排序:
cpp复制struct Person {
std::string name;
int age;
};
std::vector<Person> people = /*...*/;
// 传统排序方式
std::sort(people.begin(), people.end(),
[](const Person& a, const Person& b) {
return a.age < b.age;
});
这种写法有几个明显的问题:
- 需要显式写出begin/end迭代器
- 需要定义lambda表达式
- 当排序条件复杂时,代码会变得冗长难读
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. std::ranges的基本用法
C++20的ranges库提供了更简洁的写法:
cpp复制std::ranges::sort(people, std::less{}, &Person::age);
这里:
- 不再需要指定迭代器范围
- 使用成员指针
&Person::age直接指定排序依据 - 代码行数减少50%,可读性大幅提升
3. 投影函数的工作原理
投影(Projection)是ranges算法的一个核心概念。它允许我们在应用比较操作前,先对元素进行转换。其工作流程如下:
- 算法获取一个元素
- 对该元素应用投影函数
- 对投影结果进行比较
以排序为例:
cpp复制std::ranges::sort(range, comp, proj);
等效于伪代码:
code复制for each element in range:
transformed = proj(element)
// 使用transformed进行比较
4. 成员指针作为投影函数
成员指针是最简单的投影函数形式。对于&Person::age:
- 接受一个Person对象
- 返回其age成员
- 类型为
int Person::*
优势:
- 无需额外定义函数
- 编译器能很好优化
- 代码自文档化
5. 自定义投影函数实现
当需
