# std::compare_3way

From cppreference.com
< cpp‎ | algorithm

Defined in header `<algorithm>` |  |
template< class T, class U > constexpr auto compare_3way( const T& a, const U& b ); |  | (since C++20)

Compares two values using three-way comparison and produces a result of the strongest applicable comparison category type.

In detail:

- If the expression a <=> b is well-formed, returns its result
- Otherwise, if the expressions a == b and a < b are both well-formed and convertible to bool,

  - if a == b equals true, returns std::strong_ordering::equal
  - otherwise, if a < b equals true, returns std::strong_ordering::less
  - otherwise, returns std::strong_ordering::greater

- Otherwise, if the expression a == b is well-formed and convertible to bool (but a < b is not),

  - if a == b equals true, returns std::strong_equality::equal
  - otherwise, returns std::strong_equality::nonequal

- Otherwise (if neither a <=> b nor a == b are well-formed), the function is defined as deleted.

### Parameters

a, b | - | the values to compare

### Return value

As defined above.

### Notes

This function is useful in generic programming, since it uses < and == as fallbacks when <=> is not available.

### Example

Run this code

    #include <iostream>
    #include <compare>
    #include <algorithm>

    //does not support <=>
    struct Rational_1 {
        int num;
        int den; // > 0
    };

    inline constexpr bool operator<(Rational_1 lhs, Rational_1 rhs)
    {
        return lhs.num * rhs.den < rhs.num * lhs.den;
    }

    inline constexpr bool operator==(Rational_1 lhs, Rational_1 rhs)
    {
        return lhs.num * rhs.den == rhs.num * lhs.den;
    }

    //supports <=>
    struct Rational_2 {
        int num;
        int den; // > 0
    };

    inline constexpr std::weak_ordering operator<=>(Rational_2 lhs, Rational_2 rhs)
    {
        return lhs.num * rhs.den <=> rhs.num * lhs.den;
    }

    void print(std::weak_ordering value)
    {
        if (value == 0)
            std::cout << "equal";
        else if (value < 0)
            std::cout << "less";
        else
            std::cout << "greater";
        std::cout << "\n";
    }

    int main()
    {
        Rational_1 a{1,2};
        Rational_1 b{3,4};
    //  print(a <=> b);                //doesn't work
        print(std::compare_3way(a,b)); //works, defaults to < and ==

        Rational_2 c{6,5};
        Rational_2 d{8,7};
        print(c <=> d);                //works
        print(std::compare_3way(c,d)); //works
    }

Output:

    less
    greater
    greater

### See also

lexicographical_compare_3way (C++20) | compares two ranges using three-way comparison (function template)
strong_equality (C++20) | the result type of 3-way comparison that supports only equality/inequality and is substitutable (class)
weak_equality (C++20) | the result type of 3-way comparison that supports only equality/inequality and is not substitutable (class)
strong_ordering (C++20) | the result type of 3-way comparison that supports all 6 operators and is substitutable (class)
weak_ordering (C++20) | the result type of 3-way comparison that supports all 6 operators and is not substitutable (class)
partial_ordering (C++20) | the result type of 3-way comparison that supports all 6 operators, is not substitutable, and allows incomparable values (class)

Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/algorithm/compare_3way&oldid=109780"