Let simplify to operator==
and operator!=
.
If I have ..operator==..=default;
then I do not need to have the operator!=
to be defaulted.
struct S {
bool operator==(const S&) const = default;
// the line below not needed to do S{} != S{}
bool operator!=(const S&) const = default;
};
If I do not have ..operator==..=default;
then adding ..operator!=..=default;
is pointless because it is deleted anyway - and I can't do !=
struct S {
// allowed - but it is deleted when neither operator<=> defaulted nor operator== defined
bool operator!=(const S&) const = default;
};
S{} != S{}; // does not compile - operator!= is deleted
Same is for operator<=>
and all operator<
, operator<=
, ...
So the question. Is there any real usage of writing any of these:
bool operator!=(const S&) const = default;
bool operator<(const S&) const = default;
bool operator>(const S&) const = default;
bool operator<=(const S&) const = default;
bool operator>=(const S&) const = default;
If you have some fixed ABI:
// header
struct X {
// ...
friend bool operator==(const X&, const X&);
friend bool operator!=(const X&, const X&);
};
// source
bool operator==(const X& l, const X& r) { /* ... */ }
bool operator!=(const X&, const X&) = default;
Or if you wish to take the address of operator!=
(say to pass to some algorithm), which wouldn't exist if you didn't define it. This is the reason given in P0515R3:
Note
=default
for two-way operators is useful to conveniently force the creation of functions whose addresses can be taken.