21 Feb 2013 redi   » (Master)

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.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!