Daily bit(e) C++ #46, Три типа результатов сравнения: std::strong_ordering, std::weak_ordering и std::partial_ordering.

С оператором космического корабля C++20 мы также получили три типа результатов сравнения: std::strong_ordering, std::weak_ordering и std::partial_ordering.

Равенство std::strong_ordering подразумевает, что значения неразличимы, а std::partial_ordering — единственный порядок, допускающий несравнимые значения (где все a < b, a > b, a == b возвращают false).

#include <cmath>

struct Coord {
    int x;
    int y;
    friend auto operator<=>(const Coord&, const Coord&) = default;
};

// Integral types are strongly ordered
static_assert(std::is_same_v<decltype(0 <=> 1), std::strong_ordering>);
// Aggregates formed from strongly ordered components end up 
// also strongly ordered
static_assert(std::is_same_v<decltype(Coord{0,0} <=> Coord{1,1}),
               std::strong_ordering>);

// Notably floating-point numbers are only partially ordered:
static_assert(std::is_same_v<decltype(-0.0<=>0.0),
               std::partial_ordering>);

bool r1 = -0.0 == 0.0;
bool r2 = std::signbit(-0.0) == std::signbit(0.0);
// r1 == true, r2 == false
// -0.0 and 0.0 are equivalent, but distinguishable

bool r3 = NAN == 0.0 || NAN < 0.0 || NAN > 0.0;
// r3 == false, NaN is unordered

Откройте пример в Compiler Explorer.