c++ - Combining spaceship i.e. three-way comparison operator together of specific members - Stack Overflow

admin2025-04-16  6

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

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

Share Improve this question edited 19 hours ago marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Feb 3 at 8:48 SuperlokkusSuperlokkus 5,0891 gold badge29 silver badges64 bronze badges 1
  • How to do it is explained at the bottom of this answer. – Jan Schultke Commented Feb 3 at 9:55
Add a comment  | 

1 Answer 1

Reset to default 4

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)
转载请注明原文地址:http://anycun.com/QandA/1744774085a87433.html