On Sun, 5 Feb 2023, 12:42 Avi Kivity via Std-Proposals, <std-proposals@lists.isocpp.org> wrote:
How about:

struct s {
    int id;
    std::string name;

    auto operator<=>(const s& x) const { return for_compare() <=> x.for_compare(); }
private:
    auto for_compare() const { return std::forward_as_tuple(id); }
};

This can be used to omit certain fields, change the ordering, negate a field to reverse to comparison sense, etc.


You can also use a wrapper like:

template<typename T> struct NoCompare {
 T t;
  constexpr bool operator==(const NoCompare&) const noexcept { return true; }
};

Now a defaulted comparison in the enclosing class isn't affected by this member.

This can be achieved fairly easily with simple library solutions, there's no need for new language rules. It's also completely inappropriate for an attribute, since attributes should be ignorable and still produce correct programs.



On Mon, 2023-01-16 at 21:26 +0000, joeri _ via Std-Proposals wrote:

The introduction of a standard attribute [[nocompare]] which can be used to indicate that a suboject of T should be omitted from a defaulted comparison.

 

struct s {

    int id;

    [[nocompare]] std::string name;

 

    auto operator<=>(s const&) const = default;

};

 

Only member 'id' of class 's' will be compared when ordering or testing objects of 's' for equality. This prevents having to define all the relational operators when only wanting to opt-out a single data-member, and it mitigates the user of having to write dry and error-prone code.