Defining operator< for a struct

Kristopher Johnson picture Kristopher Johnson · Oct 7, 2010 · Viewed 63.7k times · Source

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

Konrad Rudolph picture Konrad Rudolph · Apr 18, 2013

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.