c++c++20spaceship-operator

Combining spaceship i.e. three-way comparison operator together of specific members


I got an old class that needs the comparison operation, because we want to order it by its members in the order of the members.

The old class definition was simply:

struct old_class {
    std::string a;
    std::optional<std::string> b;
    std::optional<std::string> c;

    friend auto operator<=>(const old_class&,
                            const old_class&) = default;
};

However now another data field/member is added, but is should not be used in the comparison operation, so AFAIK I got to supply my own operator<=>, but I confused how to write one with the same behavior as in the old class:

struct new_class {
    std::string a;
    std::optional<std::string> b;
    std::optional<std::string> c;

    int new_data_field_not_to_be_compared;

    friend auto operator<=>(const new_class& lhs,
                            const new_class& rhs) -> std::strong_ordering {
        return (std::tie(lhs.a,rhs.a) <=> std::tie(lhs.b,rhs.b)) <=> std::tie(lhs.c,rhs.c);
    }
};

How do I correct new_class::operator<=>?

MRE on coliru


Solution

  • std::tie(lhs.a,rhs.a) <=> std::tie(lhs.b,rhs.b)

    This compares the two (mandatory) strings a with the two optional strings b. A member of lhs is compared to a different member of lhs, ditto rhs members.

    To have the same behaviour as the previous = default you need to compare the members of lhs with the corresponding members of rhs.

    std::tie(lhs.a, lhs.b, lhs.c) <=> std::tie(rhs.a, rhs.b, rhs.c)