Would this class have a Strict Weak Ordering
Say I had class/struct Foo
struct Foo {
int a, b;
bool operator< (Foo const& r){
return a < r.a;
}
bool operator== (Foo const&开发者_运维百科amp; r){
return a==r.a&&b==r.b;
}
};
Foo bar = { 5, 1 };
Foo baz = { 5, 2 };
Now bar == baz
is false but so are bar < baz
and baz < bar
.
Note that here the ordering completely ignores b
but b
is part of the equality relation.
Technically yes, you are ordering them by the a
member directly, which should be fine for eg. std::set
. Basically they behave like integers, ie. if a < b and b < c then a < c, etc. I don't think operator == affects the validity of the ordering implied by operator <.
However - it is a bad idea to define two operators on the same class which imply different things about it, because it is likely to prove confusing to users of that class. As far as I know it wouldn't directly break any STL containers since they use only one of the two operators, but it would certainly confuse me that you can have this case where !(bar < baz) and !(baz < bar) but !(bar == baz).
In a case like this I would prefer to provide as a member only the operator that is more natural for the class, and make the other available through a standalone struct that can be supplied as a template parameter to the STL container. To me that makes it clearer that it's a way of ordering instances of the class which isn't necessarily equivalent to the other member operators.
According to the Wikipedia entry on strict weak ordering, it has the following properties:
- For all x, it is not the case that x < x (irreflexivity).
- For all x ≠ y, if x < y then it is not the case that y < x (asymmetric).
- For all x, y, and z, if x < y and y < z then x < z (transitivity).
- For all x, y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of equivalence).
operator<
for your class satisfies all these properties, and that by itself is sufficient to qualify as having strict weak ordering, because by definition the binary relationship required is <
, not ==
.
However, as Peter mentions in his answer, defining operator==
that takes into consideration an additional member variable can lead to unintuitive results that will likely confuse the users of your class.
Classes don't have weak ordering per se. A strict weak order is a binary function, like operator<(Foo, Foo)
. Once you realize that, it's obvious why function F
can't influence whether function G
is a SWO - it's an independent property of G
. That's why operator==
can't influence whether operator<
is a SWO.
精彩评论