使用设置更少或less_equal

less or less_equal using set

本文关键字:less equal 设置      更新时间:2023-10-16

我们可以将函数作为<(更少(运算符传递给STL数据结构,例如setmultisetmappriority_queue,...

如果我们的函数像<=(less_equal(一样有问题吗?

是的,有一个问题。

从形式上讲,比较函数必须定义严格的弱排序,而<=不会这样做。

更具体地说,<也用于确定等价性(xy是等价的iff !(x < y) && !(y < x)(。这不适用于<=(使用该运算符会让你的集合相信对象永远不会等效(

来自有效的 STL ->第 21 项。总是让比较函数返回 false 表示相等值。

创建一个less_equal为比较类型的集合,然后将 10 插入到该集合中:

set<int, less_equal<int> > s; // s is sorted by "<="
s.insert(10); //insert the value 10

现在尝试再次插入 10:

s.insert(10);

要插入此调用,集合必须确定 10 是否已存在。我们知道就是这样。但是这套烤面包像吐司一样愚蠢,所以它必须检查。为了更容易了解当集合执行此操作时会发生什么,我们将最初称为 10插入 10A 和我们尝试插入 10B 的 10。该集合通过其内部数据结构运行,寻找插入 10B 的位置。它最终必须检查10B,看看它是否与10A相同。"相同"的定义对于关联容器是等价的,因此集合测试以查看是否10B相当于10A。在执行此测试时,它自然会使用该集合的比较功能。在此示例中,这是运算符<=,因为我们指定了less_equal作为集合的比较函数,less_equal表示运算符。集从而检查此表达式是否为真:

!(10A<= 10B)&&!(10B<= 10A) //test 10Aand 10B for equivalence
嗯,10A

和10B都是10,所以很明显,10A<= 10B.同样清楚的是,10B<= 10A。因此,上述表达式简化为

!!(true)&&!(true)

这简化了

false && false

这简直是错误的。也就是说,集合得出结论,10A 和 10B 不等价,因此不一样,因此它将 10B 插入容器中10A.从技术上讲,此操作会产生未定义的行为,但几乎是通用的结果是集合最终得到值 10 的两个副本,这意味着它不是再来一套。通过使用less_equal作为我们的比较类型,我们已经破坏了容器!此外,任何相等值返回 true 的比较函数都将做同样的事情。根据定义,相等的值不等效!

确实有问题。

比较函数应该满足严格的弱排序,而<=则不满足。