std::set 默认升序,自定义排序需传入满足严格弱序的比较对象;仿函数类需重载 const operator(),参数为 const 引用,如 struct CompareById { bool operator()(const std::pair& a, const std::pair& b) const { return a.first
std::set 默认按升序排列,要实现自定义排序,必须在定义时传入比较对象(仿函数、lambda 或函数指针),且该比较逻辑必须满足严格弱序(strict weak ordering)——否则行为未定义,常见表现是插入失败、迭代器混乱或程序崩溃。
如何定义并传入仿函数类
仿函数即重载了
operator()的结构体或类,它能保存状态,比函数指针更灵活。注意:必须为const成员函数,且参数为const引用(避免拷贝、符合 set 内部调用约定)。struct CompareById { bool operator()(const std::pair<int, std::string>& a, const std::pair<int, std::string>& b) const { return a.first < b.first; // 按 first 升序 } }; <p>std::set<std::pair<int, std::string>, CompareById> mySet;
- 类型名必须完整写出:
std::set<t compare></t>,不能省略第二个模板参数- 仿函数类无需实例化,
std::set内部会默认构造一个临时对象- 若需带状态(如逆序开关),可在构造时传参,并在成员变量中保存
使用 lambda 作为比较器的限制与写法
lambda 可读性好,但因类型唯一且不可名状,不能直接用于模板参数;必须用
decltype推导,或封装进std::function(不推荐,有性能开销)。最实用写法是就地声明 +decltype:立即学习“C++免费学习笔记(深入)”;
auto cmp = [](const int& a, const int& b) { return a % 10 < b % 10; }; std::set<int, decltype(cmp)> s1(cmp); // 必须显式传入实例! <p>// 错误:未提供实例,编译失败 // std::set<int, decltype(cmp)> s2; // ❌
- lambda 必须是无捕获(capture-less),否则类型不可默认构造
- 必须在定义容器时传入 lambda 实例(如
cmp),仅类型不足以构造 set- 每次定义新 set 都要重复写
decltype+ 实例,不适合复用场景常见错误:违反严格弱序导致 undefined behavior
最典型的错误是把
、<code>!=或逻辑反向写成>而非!关系。例如以下写法会导致插入异常甚至死循环:// ❌ 危险!不满足 irreflexivity(a < a 必须为 false) bool operator()(const T& a, const T& b) const { return a.key <= b.key; // 错!应为 < } <p>// ❌ 危险!不满足 transitivity(传递性难保证) bool operator()(const T& a, const T& b) const { return std::abs(a.x - b.x) < 1e-5; // 浮点近似比较禁止用于 set
- 永远只用
定义顺序,不要用 <code>>、、<code>==- 浮点数慎用作 key;若必须,应转为整数倍或用固定精度量化后比较
- 多字段比较务必用「字典序」:先比主键,相等再比次键,用
&&和||组合,别用?:简写漏掉分支为什么不能运行时切换比较逻辑
std::set的比较器在构造时绑定,其类型和行为已固化于红黑树结构中;修改比较规则相当于重构整棵树,标准库不支持。若需多种排序视图,正确做法是:
- 维护原始数据容器(如
std::vector),按需用std::sort+ 不同 lambda 排序- 用多个
std::set各自配不同比较器,共享同一份数据(注意同步更新)- 改用
std::map<key value></key>存主键,再用索引std::set<key comp></key>维护排序关系仿函数不是语法糖,它是 set 正确工作的契约基础——写错一个符号,整个容器就不可靠。
相关文章
花生AI怎么用本地素材替换自动配图_花生AI本地画面替换教程
火山引擎怎么避免JSON前后夹杂解释_火山引擎纯JSON响应配置要点
VibeKnow怎么控制流程动画的播放顺序
Seko AI一个镜头里能安排多种运镜吗_Seko AI复杂运镜拆分建议
updream怎么在画布里集中摆放场景参考_updream场景参考区布局指南
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门AI工具
相关专题
Sass和less的区别有语法差异、变量和混合器的定义方式、导入方式、运算符的支持、扩展性等。本专题为大家提供Sass和less相关的文章、下载、课程内容,供大家免费下载体验。
3027
2023.10.12
sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。
1158
2023.09.04
const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。
2338
2023.09.20
在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。
6959
2023.08.02
Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。
100
2026.10.28
热门下载
相关下载
精品课程
共0课时 | 0人学习
共0课时 | 0人学习
共0课时 | 0人学习
最新文章













