Difference between revisions of "cpp/utility/compare/compare three way"
From cppreference.com
(P1614R2) |
(Wording update. All usages of {{cpp/utility/functional/pointer order}} are eliminated.) |
||
(16 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
{{cpp/title|compare_three_way}} | {{cpp/title|compare_three_way}} | ||
− | {{cpp/utility/navbar}} | + | {{cpp/utility/functional/navbar}} |
{{dcl begin}} | {{dcl begin}} | ||
− | {{dcl header | compare }} | + | {{dcl header|compare}} |
− | {{dcl | since=c++20 | | + | {{dcl header|functional}} |
+ | {{dcl|since=c++20| | ||
struct compare_three_way; | struct compare_three_way; | ||
}} | }} | ||
{{dcl end}} | {{dcl end}} | ||
− | Function object for performing comparisons. Deduces the parameter types of the function call operator | + | Function object for performing comparisons. Deduces the parameter types and the return type of the function call operator. |
− | === | + | ===Nested types=== |
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc hitem| | + | {{dsc hitem|Nested type|Definition}} |
− | {{dsc | {{tt|is_transparent}} | / | + | {{dsc|{{tt|is_transparent}}|[[cpp/utility/functional#Transparent function objects|unspecified]]}} |
{{dsc end}} | {{dsc end}} | ||
===Member functions=== | ===Member functions=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc mem fun | operator() | nolink=true | obtains the result of three-way comparison on both arguments}} | + | {{dsc mem fun|operator()|nolink=true|obtains the result of three-way comparison on both arguments}} |
{{dsc end}} | {{dsc end}} | ||
{{member|1={{small|std::compare_three_way::}}operator()|2= | {{member|1={{small|std::compare_three_way::}}operator()|2= | ||
− | {{ | + | {{ddcl| |
− | + | template< class T, class U > | |
− | template<class T, class U> | + | constexpr auto operator()( T&& t, U&& u ) const; |
− | + | ||
− | + | ||
− | + | ||
− | constexpr auto operator()(T&& t, U&& u) const; | + | |
}} | }} | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | Given the expression {{c|1=std::forward<T>(t) <=> std::forward<U>(u)}} as {{c|expr}}: | |
+ | * If {{c|expr}} results in a call to [[cpp/language/operator comparison#Built-in pointer equality comparison|built-in]] {{c/core|1=operator<=>}} comparing pointers, given the {{lsd|cpp/language/pointer#Composite pointer type}} of {{c|t}} and {{c|u}} as {{tt|P}}: | ||
+ | :* Compares the two converted pointers (of type {{tt|P}}) in the [[cpp/language/operator comparison#Pointer total order|implementation-defined strict total order over pointers]]: | ||
+ | ::* If {{c|t}} precedes {{c|u}}, returns {{ltt|cpp/utility/compare/strong_ordering|std::strong_ordering::less}}. | ||
+ | ::* If {{c|u}} precedes {{c|t}}, returns {{ltt|cpp/utility/compare/strong_ordering|std::strong_ordering::greater}}. | ||
+ | ::* Otherwise, returns {{ltt|cpp/utility/compare/strong_ordering|std::strong_ordering::equal}}. | ||
+ | :* If the conversion sequence from {{tt|T}} to {{tt|P}} or the conversion sequence from {{tt|U}} to {{tt|P}} is not [[cpp/concepts#Equality preservation|equality-preserving]], the behavior is undefined. | ||
+ | * Otherwise: | ||
+ | :* Returns the result of {{c|expr}}. | ||
+ | :* If {{c|std::three_way_comparable_with<T, U>}} is not modeled, the behavior is undefined. | ||
− | {{cpp/ | + | {{cpp/enable if|{{c|std::three_way_comparable_with<T, U>}} is satisfied}}. |
}} | }} | ||
===Example=== | ===Example=== | ||
{{example|code= | {{example|code= | ||
+ | #include <compare> | ||
#include <iostream> | #include <iostream> | ||
− | + | ||
− | + | struct Rational | |
− | + | { | |
− | + | ||
int num; | int num; | ||
int den; // > 0 | int den; // > 0 | ||
+ | |||
+ | // Although the comparison X <=> Y will work, a direct call | ||
+ | // to std::compare_three_way{}(X, Y) requires the operator== | ||
+ | // be defined, to satisfy the std::three_way_comparable_with. | ||
+ | constexpr bool operator==(Rational const&) const = default; | ||
}; | }; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | constexpr std::weak_ordering operator<=>(Rational lhs, Rational rhs) | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
{ | { | ||
return lhs.num * rhs.den <=> rhs.num * lhs.den; | return lhs.num * rhs.den <=> rhs.num * lhs.den; | ||
} | } | ||
− | + | ||
void print(std::weak_ordering value) | void print(std::weak_ordering value) | ||
{ | { | ||
− | + | value < 0 ? std::cout << "less\n" : | |
− | + | value > 0 ? std::cout << "greater\n" : | |
− | + | std::cout << "equal\n"; | |
− | + | ||
− | + | ||
− | + | ||
} | } | ||
− | + | ||
int main() | int main() | ||
{ | { | ||
− | + | Rational a{6, 5}; | |
− | + | Rational b{8, 7}; | |
− | + | print(a <=> b); | |
− | + | print(std::compare_three_way{}(a, b)); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | print( | + | |
− | print(std::compare_three_way{}( | + | |
} | } | ||
− | | output= | + | |output= |
− | + | ||
greater | greater | ||
greater | greater | ||
}} | }} | ||
+ | |||
+ | ===Defect reports=== | ||
+ | {{dr list begin}} | ||
+ | {{dr list item|wg=lwg|dr=3530|std=C++20|before=syntactic checks were relaxed while comparing pointers|after=only semantic requirements are relaxed}} | ||
+ | {{dr list end}} | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
+ | {{dsc inc|cpp/utility/functional/ranges/dsc equal_to}} | ||
+ | {{dsc inc|cpp/utility/functional/ranges/dsc not_equal_to}} | ||
+ | {{dsc inc|cpp/utility/functional/ranges/dsc less}} | ||
+ | {{dsc inc|cpp/utility/functional/ranges/dsc greater}} | ||
+ | {{dsc inc|cpp/utility/functional/ranges/dsc less_equal}} | ||
+ | {{dsc inc|cpp/utility/functional/ranges/dsc greater_equal}} | ||
{{dsc end}} | {{dsc end}} | ||
− | {{langlinks|ja|zh}} | + | {{langlinks|de|es|ja|ru|zh}} |
Latest revision as of 19:58, 2 January 2024
Defined in header <compare>
|
||
Defined in header <functional>
|
||
struct compare_three_way; |
(since C++20) | |
Function object for performing comparisons. Deduces the parameter types and the return type of the function call operator.
Contents |
[edit] Nested types
Nested type | Definition |
is_transparent
|
unspecified |
[edit] Member functions
operator() |
obtains the result of three-way comparison on both arguments (public member function) |
std::compare_three_way::operator()
template< class T, class U > constexpr auto operator()( T&& t, U&& u ) const; |
||
Given the expression std::forward<T>(t) <=> std::forward<U>(u) as expr:
- If expr results in a call to built-in operator<=> comparing pointers, given the composite pointer type of t and u as
P
:
- Compares the two converted pointers (of type
P
) in the implementation-defined strict total order over pointers:
- If t precedes u, returns std::strong_ordering::less.
- If u precedes t, returns std::strong_ordering::greater.
- Otherwise, returns std::strong_ordering::equal.
- If the conversion sequence from
T
toP
or the conversion sequence fromU
toP
is not equality-preserving, the behavior is undefined.
- Compares the two converted pointers (of type
- Otherwise:
- Returns the result of expr.
- If std::three_way_comparable_with<T, U> is not modeled, the behavior is undefined.
This overload participates in overload resolution only if std::three_way_comparable_with<T, U> is satisfied.
[edit] Example
Run this code
#include <compare> #include <iostream> struct Rational { int num; int den; // > 0 // Although the comparison X <=> Y will work, a direct call // to std::compare_three_way{}(X, Y) requires the operator== // be defined, to satisfy the std::three_way_comparable_with. constexpr bool operator==(Rational const&) const = default; }; constexpr std::weak_ordering operator<=>(Rational lhs, Rational rhs) { return lhs.num * rhs.den <=> rhs.num * lhs.den; } void print(std::weak_ordering value) { value < 0 ? std::cout << "less\n" : value > 0 ? std::cout << "greater\n" : std::cout << "equal\n"; } int main() { Rational a{6, 5}; Rational b{8, 7}; print(a <=> b); print(std::compare_three_way{}(a, b)); }
Output:
greater greater
[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3530 | C++20 | syntactic checks were relaxed while comparing pointers | only semantic requirements are relaxed |
[edit] See also
(C++20) |
constrained function object implementing x == y (class) |
(C++20) |
constrained function object implementing x != y (class) |
(C++20) |
constrained function object implementing x < y (class) |
(C++20) |
constrained function object implementing x > y (class) |
(C++20) |
constrained function object implementing x <= y (class) |
(C++20) |
constrained function object implementing x >= y (class) |