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.
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.
1 Answer
Reset to default 31According 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.