🚀intermediate
Ordering Categories
Understand strong, weak, and partial ordering
Example Code
cpp
#include <compare>#include <iostream>#include <cmath>// Strong ordering: equal values are indistinguishablestruct IntWrapper { int value; std::strong_ordering operator<=>(const IntWrapper&) const = default;};// Weak ordering: equivalent values may be distinguishablestruct CaseInsensitiveString { std::string value; std::weak_ordering operator<=>(const CaseInsensitiveString& other) const { auto to_lower = [](char c) { return static_cast<char>(std::tolower(c)); }; std::string a, b; std::transform(value.begin(), value.end(), std::back_inserter(a), to_lower); std::transform(other.value.begin(), other.value.end(), std::back_inserter(b), to_lower); if (a < b) return std::weak_ordering::less; if (a > b) return std::weak_ordering::greater; return std::weak_ordering::equivalent; } bool operator==(const CaseInsensitiveString& other) const { return (*this <=> other) == 0; }};// Partial ordering: some values are incomparable (like NaN)struct FloatWrapper { double value; std::partial_ordering operator<=>(const FloatWrapper& other) const { return value <=> other.value; // Handles NaN correctly } bool operator==(const FloatWrapper& other) const = default;};int main() { CaseInsensitiveString s1{"Hello"}; CaseInsensitiveString s2{"HELLO"}; std::cout << std::boolalpha; std::cout << "Hello == HELLO: " << (s1 == s2) << std::endl; // true FloatWrapper nan{std::nan("")}; FloatWrapper one{1.0}; auto result = nan <=> one; std::cout << "NaN vs 1: unordered = " << (result == std::partial_ordering::unordered) << std::endl; // true return 0;}Explanation
C++20 provides three ordering categories. Strong ordering means equal values are identical. Weak ordering allows equivalence without equality. Partial ordering handles incomparable values like NaN.
Key Points
- 1strong_ordering: equal = identical
- 2weak_ordering: equivalent but distinguishable
- 3partial_ordering: allows incomparable values
- 4Floating-point uses partial_ordering