std::set 自定义比较函数用于双精度值插入不起作用

问题描述

我通过

创建了一个集合
bool(*fn_pt)(const double&,const double&) = comp_double;
std::set<double,bool(*)(const double&,const double&) > values(fn_pt);

其中我的 comp_double 函数

给出
bool comp_double (const double& p1,const double& p2)
{
return (std::abs(p1-p2)<1e-05);
}

我插入了两个虚拟元素,values.insert(0.01) 和 values.insert(0.02),但我的集合的大小仍然为零。 没有编译器警告或错误,所以我猜问题出在我的 comp_double 函数中。任何输入将不胜感激!

最佳

解决方法

首先,我们应该记住 std::set 是一个关联容器 (仅包含“键”)。是的,我们可以为关联容器提供我们自己的比较操作。此操作必须符合严格的弱排序(我们可以将其视为“小于”),意味着具有以下属性:

  • 两个键不能同时“小于”彼此。 (此外,密钥不能与自身产生“较少”)
  • 比较必须是可传递的。如果key1 < key2key2 < key3,则key1 < key3
  • 如果我们有两个键并且它们都不“小于”另一个,则它们必须是等价的。

考虑这种情况:

key1 = 0.000001;
key2 = 0.000002;

abs(key1 - key2) == 0.000001; // which is less than 0.00001,true
abs(key2 - key1) == 0.000001; // same,true too

它们中的每一个都比另一个“少”,这意味着它们违反了第一个约束。此外,这里的一个键将对自身的“less”产生真

您可能想看看:Does using epsilon in comparison of floating-point break strict-weak-ordering?

有关 Compare 要求的更多信息,请查看 documentation