电话
400 9058 355
set插入自动去重依赖红黑树的二分查找与等价判断(非相等),要求比较函数满足严格弱序;若自定义类型仅重载operator==而未提供operator
std::less 和等价判断不是靠“查重后再插入”,而是靠红黑树的插入逻辑:每次插入先按排序规则(默认 std::less)做二分查找,若已存在「等价」元素(即既不小于也不大于),就直接丢弃。这里的关键是「等价」≠「相等」——对 int 没区别,但自定义类型若只重载了 operator== 却没适配比较函数,set 仍会插入“看似重复”的元素。
常见错误现象:set 插入两个字段完全相同的对象,结果 size 变成 2。原因往往是只写了 operator==,却没提供 operator 或自定义 Compare 函数对象。
return a.x == b.x && a.y == b.y 当 operator —— 这不满足严格弱序

return std::tie(a.x, a.y)
因为 set 的核心契约是「有序 + 去重」,不是「快查」。红黑树天然支持 O(log n) 插入/删除/查找,且中序遍历即升序;而哈希表(如 unordered_set)虽平均 O(1),但不保证顺序,也无法直接支持 lower_bound、upper_bound 等范围操作。
性能影响明显:如果你只需要去重、不关心顺序,unordered_set 更快;但一旦需要迭代有序、或频繁调用 lower_bound 查找前驱后继,set 是唯一合理选择。
立即学习“C++免费学习笔记(深入)”;
set 迭代器是双向迭代器,可 ++/--;unordered_set 是前向迭代器,只能 ++set::find 返回指向有序位置的迭代器;unordered_set::find 返回任意位置的迭代器set::insert 返回 std::pair,其中 bool 表示是否成功插入(true = 新元素,false = 已存在)。这不是“手动去重”,而是标准协议的一部分,用于判断是否发生实际变更。
容易踩的坑:有人误用 set::emplace_hint 并传错 hint,导致性能退化甚至逻辑错误;还有人把 set 当作临时去重容器,反复构造再清空,其实不如直接用 std::vector + std::sort + std::unique(尤其数据量小或只去重一次时)。
set s(v.begin(), v.end()); ,比循环 insert 快(内部优化为批量建树)unordered_set + vector 构造更快set 调用 std::unique —— 它要求相邻重复,而 set 根本不会存重复当 set 明明该去重却没去,优先检查三件事:
MyClass 的比较函数是否被正确使用:在 set 模板参数里显式传入,或确保 operator 是 public 且非模板
s.size() 和遍历输出,验证是否真没去重,还是你误判了“相同”逻辑(比如浮点数直接比较)std::is_sorted(s.begin(), s.end(), comp) 检查是否真有序——如果返回 false,说明比较函数违反严格弱序,这是根本原因最隐蔽的问题:比较函数里用了未初始化成员、或依赖外部状态(如全局变量),导致行为不稳定。这种 bug 往往只在特定编译器或优化等级下暴露。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...