这可能是一个枯燥的问题,但我想确定。 让我们说我有一个结构:
struct A
{
int number;
bool flag;
bool operator<(const A& other) const
{
return number < other.number;
}
};
代码中的某处:
A a1, a2, a3;
std::set<A> set;
a1.flag = true;
a1.number = 0;
a2.flag = false;
a2.number = 10;
a3 = a1;
set.insert(a1);
set.insert(a2);
if(set.find(a3) == set.end())
{
printf("NOT FOUND");
}
else
{
printf("FOUND");
}
我得到的输出是&#34; FOUND&#34;。我理解,因为我传递值,所以set中的元素按值进行比较。但是,对象A如何通过它们的值进行比较,因为相等运算符没有被覆盖?我不明白最重要的操作符&#39;&lt;&#39;对于集合查找功能来说已经足够了。
答案 0 :(得分:3)
有序容器(set,multiset,map,multimap)使用一个谓词来建立元素顺序并查找值 less-than 谓词。
如果两个元素都不小于另一个元素,则认为它们是相等的。
这个概念如果“平等”可能与你可能拥有的其他平等概念不同。有时候,“等价”这个术语更倾向于区分这种概念,这种概念是由可能同时存在的其他特殊的平等概念(例如,过载的operator==
)所引起的,而不是排序。
对于“理智”的值类型(也称为常规类型),ad-hoc相等和低于诱导的等价要求是相同的;许多自然发生的类型是规则的(例如算术类型(如果NaN被移除))。在其他情况下,特别是如果小于谓词是在外部提供而不是由类型本身提供的,那么小于等价类完全有可能包含许多非“相等”的值。
答案 1 :(得分:2)
flag
成员在这里完全无关紧要。 set
找到的元素与搜索到的值相同,相对于&lt; 。
即,如果a不小于b,并且b不小于a,则a和b必须相等。这是正常整数的工作原理。这就是决定std::set
中2个值是等价的方式。
std::set
根本不使用==
。 (unordered_set
,它是一个哈希集,确实使用它,因为它是区分哈希冲突的唯一方法。)
您还可以提供执行<
工作的功能,但它必须表现为strict weak ordering。这对数学来说有点沉重,但基本上你可以通过std::greater
使用>
,或者定义你自己的命名函数而不是定义operator<
。
所以从技术上讲,没有什么可以阻止你定义一个operator==
,其行为与operator<
的等价概念不同,但std::set
不会使用它,这可能会让人感到困惑。
答案 2 :(得分:1)
来自set
的文档两个对象a和b被认为是等价的(不唯一) 比较少:!comp(a,b)&amp;&amp; !comp(b,a)
http://en.cppreference.com/w/cpp/container/set
在模板中,您可以看到
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class set;
的std ::以下
将致电operator<
,这就是它的原因。