Kristopher Johnson Kristopher Johnson - 3 months ago 13
C++ Question

Defining operator< for a struct

I sometimes use small

structs
as keys in maps, and so I have to define an
operator<
for them. Usually, this ends up looking something like this:

struct MyStruct
{
A a;
B b;
C c;

bool operator<(const MyStruct& rhs) const
{
if (a < rhs.a)
{
return true;
}
else if (a == rhs.a)
{
if (b < rhs.b)
{
return true;
}
else if (b == rhs.b)
{
return c < rhs.c;
}
}

return false;
}
};


This seems awfully verbose and error-prone. Is there a better way, or some easy way to automate definition of
operator<
for a
struct
or
class
?

I know some people like to just use something like
memcmp(this, &rhs, sizeof(MyStruct)) < 0
, but this may not work correctly if there are padding bytes between the members, or if there are
char
string arrays that may contain garbage after the null terminators.

Answer

This is quite an old question and as a consequence all answers here are obsolete. C++11 allows a more elegant and efficient solution:

bool operator <(const MyStruct& x, const MyStruct& y) {
    return std::tie(x.a, x.b, x.c) < std::tie(y.a, y.b, y.c);
}

Why is this better than using boost::make_tuple? Because make_tuple will create copies of all the data members, which can be costly. std::tie, by contrast, will just create a thin wrapper of references (which the compiler will probably optimise away entirely).

In fact, the above code should now be considered the idiomatic solution to implementing a lexicographical compare for structures with several data members.

Comments