Mathias Hasselmann

Operator Overloading

Just wondered right now why Qt doesn't provide a greater-than operator for QSize.

Well, indeed: How would you define this operator? Maybe like this?

inline bool 
operator >(const QSize &a, const QSize &b)
{
    return a.width() * a.height() > b.width() * b.height();
}

Or is this the proper definition?

inline bool 
operator >(const QSize &a, const QSize &b)
{
    return (a.width() > b.width() || a.height() > b.height());
}

Mathematician might intuitively choose the first alternative, aka. covered area. I claim for UI problems usually the second interpretation is useful.

Funnily the Qt author(s) of QSize implicitly agree with my claim, as they provide:

inline bool QSize::isValid() const
{
    return wd>=0 && ht>=0; 
}

Which gives "(b - a).isValid()" computing the same result as my preferred interpretion of the greater-than operator.

Well, my currently preferred interpretion, within the scope of my current problem. Oh, and sans integer overflows and such "minor problems" - of course. Someone really cares about such "minor details"? :-)

So what tells this? API design is fun. Even more if you add operator overloading to the soup.

*Disclaimer: There is nothing Qt specific in this post. It only provides the example. *

Comments

Marco Barisione commented on September 15, 2010 at 11:11 p.m.

If you use the second definition then you would have that QSize(5, 3) > QSize(4, 4), but also QSize(4, 4) > QSize(5, 3). That doesn't make much sense.

Philip Withnall commented on September 15, 2010 at 11:16 p.m.

I'm not sure it would be wise to define a comparison operator for this type, since whatever you define is going to be non-intuitive for half of the users of the API, so they're going to either misuse it or waste time looking up the specifics of the total order you've defined.

For example, they don't know if you chose either of the examples you gave, or one of these:
http://en.wikipedia.org/wiki/Total_or...

Mathieu Rochette commented on September 15, 2010 at 11:16 p.m.

I think there is no > operator for QSize because the definition would be ambiguous (greater area, greater width or greater height)

your preferred solution is not viable, eg say we have two QSize a = (1, 2) and b = (2, 1)

a > b == true
b > a == true

not really good. < and > are usually define asymmetric transitive relation (http://en.wikipedia.org/wiki/Relation...)

the first solution might be correct.

and at last, I don't think QSize:isValid has anything to do with comparison.

Benjamin Otte commented on September 16, 2010 at 12:07 a.m.

I suspect he means &&, not || in that second example.

In both cases, operator overloading is problematic, because the assumption that exactly one of A < B, A == B, A > B holds is not true. And when writing sort functions, one might assume this.

Marco Barisione commented on September 16, 2010 at 12:22 a.m.

@Benjamin Otte:
If you use && you get that (5,3)>(4,4) is false, but also (4,4)>(5,3) is false. Does it mean (5,3)==(4,4)?

In general operator overloading makes sense only if you can keep clear semantics because it's similar to the behaviour you have for default type or because the new meaning is consistently used everywhere (like << in C++).

M Welinder commented on September 16, 2010 at 12:25 a.m.

The isvalid reference only is correct if he meant "&&".
That would make a fine partial ordering.

Benjamin: < for doubles is also partial.

Snark commented on September 16, 2010 at 10:25 a.m.

There are several ways to compare pairs of objects. None is better than the others, and that is why it does make sense NOT to give an implementation of that operator.

Better add biggerArea and couldContain methods... which at least are descriptive.

(aside: @Marco Barisione, it doesn't mean (5,3)==(4,4) -- you're thinking in terms of "total order", and none of the examples is of such type)

michael commented on September 16, 2010 at 6:41 p.m.

Snark wins.