std::compare_3way

< cpp‎ | algorithm
 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Concepts and utilities: std::Sortable, std::projected, ...
Constrained algorithms: std::ranges::copy, std::ranges::sort, ...
Execution policies (C++17)
Non-modifying sequence operations
(C++11)(C++11)(C++11)
(C++17)
Modifying sequence operations
Operations on uninitialized storage
Partitioning operations
Sorting operations
(C++11)
Binary search operations
Set operations (on sorted ranges)
Heap operations
(C++11)
Minimum/maximum operations
(C++11)
(C++17)
compare_3way
(C++20)
Permutations
Numeric operations
C library
 
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

#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

compares two ranges using three-way comparison
(function template)
the result type of 3-way comparison that supports only equality/inequality and is substitutable
(class)
the result type of 3-way comparison that supports only equality/inequality and is not substitutable
(class)
the result type of 3-way comparison that supports all 6 operators and is substitutable
(class)
the result type of 3-way comparison that supports all 6 operators and is not substitutable
(class)
the result type of 3-way comparison that supports all 6 operators, is not substitutable, and allows incomparable values
(class)