使用set更少或更少_equal

时间:2012-04-29 11:51:46

标签: c++ stl set

我们可以将<(less)运算符的函数传递给STL数据结构,例如setmultisetmappriority_queue,..

如果我们的函数的作用类似于<=(less_equal),那么会出现问题吗?

3 个答案:

答案 0 :(得分:8)

是的,有问题。

正式地,比较函数必须定义严格弱排序,而<=不会这样做。

更具体地说,<也用于确定等效性(xy等效于iff !(x < y) && !(y < x))。这不适用于<=(使用该运算符会使您的集合认为对象从不等效)

答案 1 :(得分:7)

来自有效STL - &gt;项目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和10我们试图插入10B。该集合贯穿其内部数据结构,寻找插入10B的位置。它最终必须检查10B以查看它是否与10A相同。 “相同”的定义 对于关联容器是等价的,所以set测试是否 10B相当于10A。执行此测试时,它自然会使用该集合 比较功能。在这个例子中,那是运算符&lt; =,因为我们指定了 less_equal作为set的比较函数,less_equal表示运算符。这套 因此检查这个表达式是否为真:

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

嗯,10A和10B都是10,所以显然10A <= 10B。同样清楚,10B &lt; = 10A。因此,上述表达简化为

!!(true)&&!(true)

并简化为

false && false

这简直是假的。也就是说,该集合断定10A和10B不相等, 因此不一样,因此将10B插入容器旁边 10A。从技术上讲,这个动作会产生不确定的行为,但几乎是普遍存在的 结果是该集合最终得到了值10的两个副本,这意味着它不是 再套一套。通过使用less_equal作为我们的比较类型,我们已经破坏了 容器!此外,任何比较函数,其中相等的值返回true将 做同样的事。根据定义,等值不等同!

答案 2 :(得分:6)

确实存在问题。

比较函数应该满足<=没有的strict weak ordering