I'm attempting to define operator<=> on a class, however when I specify a non-defaulted implementation, std::three_way_comparable returns false:
#include <cstdio>
#include <compare>
using namespace std;
struct UDTC
{
int i_;
UDTC(int i) : i_(i) {}
#if 1
friend std::strong_ordering operator<=>(const UDTC &lhs, const UDTC &rhs) {
return lhs.i_ <=> rhs.i_;
}
#else
friend std::strong_ordering operator<=>(const UDTC &lhs, const UDTC &rhs) = default;
#endif
};
int main(void)
{
if constexpr (std::three_way_comparable<UDTC>) {
fprintf(stderr, "UDTC is three_way_comparable\n");
} else {
fprintf(stderr, "UDTC is NOT three_way_comparable\n");
}
}
When I execute this with Visual Studio 2022 or GCC 12, if the <=> function is defaulted, three_way_comparable returns true. If I provide my own implementation, it returns false. I can only assume that my implementation is somehow incomplete, but I'm not seeing what I'm missing.
According to cppreference,
concept std::three_way_comparable<T> includes (exposition only) concept __WeaklyEqualityComparableWith<T, T>. In other words, to satisfy this concept, struct UDTC also needs operator==. When you use operator<=>(/*...*/) = default, the compiler also generates operator== for you. If you define your own operator<=>, you must also define operator==. If you add
friend bool operator==(const UDTC &lhs, const UDTC &rhs) {
return lhs.i_ == rhs.i_;
}
to the program, it prints "UDTC is three_way_comparable" as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With