Hey, C++ programmers, stop writing Strict Weak Orderings by hand for your classes.
For two members it's manageable:
bool operator<(const Widget& l, const Widget& r)
{
if (l.x < r.x)
return true;
if (r.x < l.x)
return false;
return l.y < r.y;
}
But for three members it starts to get tricky:
bool operator<(const Widget& l, const Widget& r)
{
if (l.x < r.x)
return true;
if (r.x < l.x)
return false;
if (l.y < r.y)
return true;
if (r.y < l.y)
return false;
return l.z < r.z;
}
If you think that's not tricky, are you sure I got it right? Maybe I put in a deliberate mistake. Maybe it wasn't deliberate. Now consider that everyone who writes that does it slightly differently e.g.
bool operator<(const Widget& l, const Widget& r)
{
return l.x < r.x ? true : r.x < l.x ? false : l.y < r.y ? true : r.y < l.y ? false : l.z < r.z;
}
Or even:
bool operator<(const Widget& l, const Widget& r)
{
return l.x < r.x || (!(r.x < l.x) && (l.y < r.y || (!(r.y < l.y) && l.z < r.z)));
}
Now do that for ten members.
Stop right now and do this instead:
bool operator<(const Widget& l, const Widget& r)
{
return std::tie(l.x, l.y, l.z) < std::tie(r.x, r.y, r.z);
}
This creates a tuple of references and does a lexicographical comparison, so it just does the Right Thing. All you have to do is list the data members in the same order in each call to the
tie
function template, and even PHP programmers could do that.
If you haven't caught up with C++ 2011 yet you can use Boost's tuple, just
#include <boost/tuple/tuple_comparison.hpp>
and then use
boost::tie
instead of
std::tie
.