来自cplusplus.com:
template < class Key, class Compare = less<Key>,
class Allocator = allocator<Key> > class set;
“比较:比较类:一个类,它接受与容器元素相同类型的两个参数并返回一个bool。表达式comp(a,b),其中comp是此比较类的对象,a和b是容器的元素,如果在严格的弱排序操作中将a放置在比b更早的位置,则返回true。这可以是实现函数调用操作符的类或指向函数的指针(参见构造函数)例如)。默认为less,返回与应用less-than运算符相同(a <
b)。
set对象使用此表达式来确定容器中元素的位置。集合容器中的所有元素始终遵循此规则进行排序。“
鉴于比较类用于决定两个对象中的哪一个是“较小”或“较小”,该类如何检查两个元素是否相等(例如,防止同一元素插入两次)?
我可以想象这里有两种方法:一种是在后台调用(a == b),但不提供覆盖此比较的选项(与默认值较少<Key>
一样)似乎也不太STL-ish给我。另一种假设是(a == b)==!(a&lt; b)&amp;&amp; !(b&lt; a);也就是说,如果两个元素都不比另一个元素“更小”,则认为它们是相等的,但是考虑到比较可以是任意复杂类的对象之间的任意复杂的bool仿函数,这对我来说也不合适。 / p>
那怎么办呢?
答案 0 :(得分:3)
不完全相同,但第一个回答here回答了您的问题
你对行为的第二次猜测是正确的
答案 1 :(得分:3)
标准库中的关联容器是根据等价键而非本身定义的。
由于并非所有set
和map
实例都使用less
,但可能会使用通用比较运算符,因此需要根据此一个比较函数定义等价,而不是尝试引入单独的平等概念。
通常,使用比较函数k1
的关联容器中的两个键(k2
和comp
)是等效的,当且仅当:
comp( k1, k2 ) == false && comp( k2, k1 ) == false
在使用std::less
的容器中,对于没有特定std :: less特化的类型,这意味着相同:
!(k1 < k2) && !(k2 < k1)
答案 2 :(得分:1)
你的错误是“比较可以是任意复杂的bool仿函数”的假设。它不能。
std::set
需要部分排序,以便a<b
隐含!(b<a)
。这排除了大多数二元布尔函子。因此,我们可以谈论a和b在该排序中的相对位置。如果a<b
,则a先于b。如果b<a
,b先于a。如果既不是a<b
也不是b<a
,那么a和b在排序中占据相同的位置,因此是等价的。
答案 3 :(得分:0)
你的第二个选择是正确的。为什么感觉不对?如果等式测试与你给出的等式不一致,你会怎么做?