C++ std::set自定义double比较函数后insert插入失效问题
问题原因分析
核心问题是你自定义的comp_double比较函数不符合std::set对比较器的**严格弱序(Strict Weak Ordering)**要求,导致内部插入逻辑完全异常:
std::set的比较器需要实现序关系判断,即返回true表示第一个参数应该排在第二个参数之前,类似默认的std::less的功能,而非你实现的近似相等判断。- 你的实现逻辑完全不满足严格弱序的基础要求:
- 违反非自反性:对同一个元素
a,comp_double(a,a)必然返回true,而严格弱序要求Compare(a,a)必须返回false - 无明确排序逻辑:比较器仅判断两个数是否接近,没有给出谁更小、谁应该排在前面的规则,导致set内部红黑树的插入、去重逻辑完全混乱,最终出现插入失败、容器大小为0的异常表现。
- 违反非自反性:对同一个元素
修复方案
修改比较器实现带精度控制的严格弱序逻辑即可:
bool comp_double (const double& p1, const double& p2) { // 仅当p1明确小于p2且差值超过精度阈值时返回true return p1 < p2 && std::abs(p1 - p2) >= 1e-5; }
该实现满足所有要求:
- 非自反性:
comp_double(a,a)必然返回false - 传递性:若
comp_double(a,b)和comp_double(b,c)都为true,则comp_double(a,c)也为true - 等价判断规则符合需求:
!comp_double(a,b) && !comp_double(b,a)成立时,说明两个数差值小于1e-5,会被set判定为重复元素拒绝插入,正好实现你需要的按精度去重的效果。
内容的提问来源于stack exchange,提问作者SolidMechanicsFan
相关产品推荐
相关产品推荐

