Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Would this class have a Strict Weak Ordering

Tags:

c++

math

stl

Say I had class/struct Foo

struct Foo {
    int a, b;
    bool operator< (Foo const& r){
        return a < r.a;
    }
    bool operator== (Foo const& 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.

like image 422
Flame Avatar asked Aug 18 '11 04:08

Flame


People also ask

What is a strict weak ordering?

A Strict Weak Ordering is a Binary Predicate that compares two objects, returning true if the first precedes the second. This predicate must satisfy the standard mathematical definition of a strict weak ordering.

What is meant by weak ordering?

In mathematics, especially order theory, a weak ordering is a mathematical formalization of the intuitive notion of a ranking of a set, some of whose members may be tied with each other.

Which analysis is an example of weak ordering in economics?

We have seen that consumer is indifferent on an indifference curve as all the points lying on it give same level of satisfaction. It implies that indifference curve shows weak ordering as all the points lying on it are giving same level of satisfaction and hence occupy same place in the order.


2 Answers

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.

like image 125
Peter Avatar answered Oct 29 '22 07:10

Peter


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.

like image 28
Praetorian Avatar answered Oct 29 '22 05:10

Praetorian