我们可以将<
(less)运算符的函数传递给STL数据结构,例如set
,multiset
,map
,priority_queue
,..
如果我们的函数的作用类似于<=
(less_equal),那么会出现问题吗?
答案 0 :(得分:8)
是的,有问题。
正式地,比较函数必须定义严格弱排序,而<=
不会这样做。
更具体地说,<
也用于确定等效性(x
和y
等效于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。