[英]Why is operator< overloading necessary for STL set containing custom objects, instead of operator==
I'm working with C++11 and I want to use set
to store my custom objects because I need a container, which can filter the elements with the same value.我正在使用 C++11,我想使用
set
来存储我的自定义对象,因为我需要一个容器,它可以过滤具有相同值的元素。
Here is the class of my custom object:这是我的自定义对象的类:
struct Ele
{
int a, b, c;
}
As my understanding, I need to overload the function operator==
because set
need to filter the elements with the same value.据我了解,我需要重载函数
operator==
因为set
需要过滤具有相同值的元素。
However, after reading this link: How do i insert objects into STL set , it seems that overloading operator<
is what I need, instead of operator==
.但是,在阅读此链接后: How do i insert objects into STL set ,似乎重载
operator<
是我需要的,而不是operator==
。
So I code like this:所以我这样编码:
struct Ele {
int a, b, c;
friend bool operator<(const Ele &e1, const Ele &e2);
};
bool operator<(const Ele &e1, const Ele &e2)
{
if (e1.a < e2.a) {
return true;
}
if (e1.a == e2.a) {
if (e1.b < e2.b) {
return true;
}
if (e1.b == e2.b) {
if (e1.c < e2.c) {
return true;
}
return false;
}
return false;
}
return false;
}
And do a test as below:并进行如下测试:
set<Ele> myset;
Ele e1;
e1.a = 1;
e1.b = 2;
e1.c = 3;
Ele e2;
e2.a = 1;
e2.b = 2;
e2.c = 3;
myset.insert(e1);
myset.insert(e2);
cout << myset.size() << endl;
Well, the output is 1
, instead of 2
, which means that the insertion for e2
failed as expected because the value of e2
is the same with the value of e1
.嗯,输出是
1
,而不是2
,这意味着e2
的插入按预期失败,因为e2
的值与e1
的值相同。
Now I'm confused.现在我很困惑。
As my understanding, operator<
just told the compiler how to understand e1 < e2
, how does compiler know how to understand e1 == e2
?根据我的理解,
operator<
只是告诉编译器如何理解e1 < e2
,编译器如何知道如何理解e1 == e2
? What if I want to set such a rule: e1 == e2
only if e1.a == e2.b && e1.b == e2.c && e1.c == e2.a
?如果我想设置这样的规则:
e1 == e2
only if e1.a == e2.b && e1.b == e2.c && e1.c == e2.a
怎么e1.a == e2.b && e1.b == e2.c && e1.c == e2.a
?
==
is not sufficient on its own to define an ordering, whereas <
is. ==
本身不足以定义排序,而<
是。 Furthermore all other relational operators can be cast in terms of operator<
, so long as you are allowed to negate the result.此外,所有其他关系运算符都可以根据
operator<
,只要您可以否定结果。
For example, a == b
if !(a < b)
and !(b < a)
例如,
a == b
if !(a < b)
and !(b < a)
<
is a natural choice insofar that thinking of things being in ascending order is natural. <
是一个自然的选择,因为认为事物按升序排列是很自然的。 >
could have been picked, but it wouldn't have been so tractable. >
可以被选中,但它不会那么容易处理。
operator<
is required because std::map
internally is implicitly required by the standard to be a tree-like data structure that requires some kind ordering between elements. operator<
是必需的,因为std::map
内部隐式要求std::map
是一个树状数据结构,需要元素之间的某种排序。 Notice that one can generate all the comparing functions using just operator<
.请注意,只需使用
operator<
即可生成所有比较函数。 Take a look:看一看:
a == b <==> !(a < b) && !(b < a)
a > b <==> b < a
a >= b <==> !(a < b)
and so on等等
You could ensure uniqueness with ==
(and !
), but it would be less efficient than using <
( std::set
) or a hash function ( std::unordered_set
).您可以使用
==
(和!
)确保唯一性,但它的效率会低于使用<
( std::set
)或散列函数( std::unordered_set
)。
Consider insert.考虑插入。 With only
==
you would have to compare every element to verify that you don't have an equal element already.只有
==
您必须比较每个元素以验证您已经没有相等的元素。 std::set
's elements are kept in order, so insert does a binary search, looking at far fewer elements. std::set
的元素按顺序排列,因此 insert 进行二分搜索,查看的元素要少得多。 std::unordered_set
's elements are kept in buckets based on the hash value, so lookup only has to search the bucket, not the whole collection. std::unordered_set
的元素根据哈希值保存在桶中,因此查找只需搜索桶,而不是整个集合。
As noted in Bathsheba's answer, you can synthesize an equality function from <
正如在Bathsheba 的回答中所指出的,您可以从
<
The other answers already point out that std::set
requires an ordering of the elements which requires operator<
to be defined for the type.其他答案已经指出
std::set
需要对需要为类型定义operator<
的元素进行排序。 If you don't care about ordering, and only care about uniqueness, you can use std::unordered_set
.如果你不关心排序,只关心唯一性,你可以使用
std::unordered_set
。
Also, here's a much cleaner way to implement the comparison:此外,这是实现比较的更简洁的方法:
bool operator<(const Ele &e1, const Ele &e2)
{
return std::tie(e1.a, e1.b, e1.c) < std::tie(e2.a, e2.b, e2.c);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.