NaN <=> NaN -> -2
..which could be reserved for a ternary, meaning "undefined". Or, any value not, -1, 0, 1.
I proposed int as to avoid exactly what happened in this thread anyway.
So, in better disclosure, I've had success in the past with a "rich" enum ternary type made for an override of a "Compare" function.
Here's a snippet:
`
enum class Relation : int
{
Undefined = -2,
Less = -1,
Equal = 0,
Greater = 1
};
inline constexpr Relation ClampToValid( Relation r ) noexcept
{
const auto u = (int)r + 1;
const auto v = 2 - u;
const auto w = u | ((u|v) >> (bitCount<int>-1));
return (Relation)( w - 1 );
}
// Relational operators that take "Relation" etc...
`
Now, if <=> could just return `int` or anything that can round-trip to an `int` implicitly, and enum classes could expose implicit conversions, this could all be safely encapsulated without creating incorrect code that tries to compare a `Relation` value and not getting the magic `undefined` result - everything would get mapped into to the set {-2,-1,0,1} before comparison. The "sign of difference" rule still applies everywhere, and comparisons are allowed to return any other random value to mean "undefined". In cases where the meaning of the return value means more than just "undefined", and the code still assumes the semantics of "Relation", it wasn't written to deal with the failure anyway (generally, just capture the original int and propagate an error/throw an exception).