'How to impose a lexicographic order on an (arbitrary) POD C++ struct?

I have some POD struct foo; suppose it's struct foo { int x; unsigned y; }. I want to be able to compare struct foo's using lexicographic order - by order of their fields of course. That is, I want all of the operators <, ==, >, etc. to work for struct foo's

Can I do this in some generic way, without having decorated my structure definition with any reflection voodoo - and without just spelling out all those operator definitions? Or is the ability to do this too much of a "language reflection dependent" expectation?



Solution 1:[1]

Can I do this in some generic way, without having decorated my structure definition with any reflection voodoo - and without just spelling out all those operator definitions?

No, there's no way to achieve such in a generic way with the current c++ standard.

I don't even know what you mean with "reflection voodo" since the standard doesn't support type reflection (yet).

And even if so in future, I have doubts that operations like list in lexicographical order would be available in first place.


Or is the ability to do this too much of a "language reflection dependent" expectation?

Probably yes. You may try with a language like c#, wich has reflection, it'll still be tricky to provide a generic operator implementation though.

Solution 2:[2]

There is currently no shortcut for something like

auto operator < (const foo &a, const foo &b) {
    return std::tie(a.x, a.y) < std::tie(b.x, b.y);
}

in standard C++ (and in Boost afaics).

As this is indeed needless and error-prone typing, Defaulted comparison operators have been proposed, but not yet added to standard C++ (as of the current draft for C++17).

Solution 3:[3]

As of C++20, it can be done simply by adding a defaulted spaceship-operator to the class,

struct foo
{
    //...

    auto operator<=>(foo const&) = default;
};

I guess that anyone interested knows that by now, but nevertheless it might be useful as an answer to the question.

Solution 4:[4]

You can't do that in standard C++11 or C++14.

You could consider having some program or script generating both the concerned struct-s and their compare function. Perhaps use some external preprocessor like GPP or m4 (or write your own C++ generator). Qt moc might be inspirational.

Or you might consider having some compiler plugin (if using GCC: coded in C++, or in MELT; if using Clang: coded in C++) to help the job. That would require perhaps several weeks of work (because C++ compilers are very complex beasts) so is worthwhile only for large programs.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Baum mit Augen
Solution 3
Solution 4 Basile Starynkevitch