Search code examples
c++c++20spaceship-operator

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


I got an old class that needs the comparision operation, because we want to order it by its members in the order of the members. So 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)