问题
While I was trying to learn about C++ operators, I stumbled upon a strange comparison operator on cppreference.com,* in a table that looked like this:
"Well, if these are common operators in C++, I better learn them", I thought. But all my attempts to elucidate this mystery were unsuccessful. Even here, on Stack Overflow I had no luck in my search.
Is there a connection between <=> and C++?
And if there is, what does this operator do exactly?
* In the meantime cppreference.com updated that page and now contains information about the<=>operator.
回答1:
This is called the three-way comparison operator.
According to the P0515 paper proposal:
There’s a new three-way comparison operator,
<=>. The expressiona <=> breturns an object that compares<0ifa < b, compares>0ifa > b, and compares==0ifaandbare equal/equivalent.To write all comparisons for your type, just write
operator<=>that returns the appropriate category type:
Return an _ordering if your type naturally supports
<, and we’ll efficiently generate<,>,<=,>=,==, and!=; otherwise return an _equality, and we’ll efficiently generate == and !=.Return strong if for your type
a == bimpliesf(a) == f(b)(substitutability, where f reads only comparison-salient state accessible using the nonprivate const interface), otherwise return weak.
The cppreference says:
The three-way comparison operator expressions have the form
lhs <=> rhs (1)The expression returns an object that
- compares
<0iflhs < rhs- compares
>0iflhs > rhs- and compares
==0iflhsandrhsare equal/equivalent.
回答2:
On 2017-11-11, the ISO C++ committee adopted Herb Sutter's proposal for the <=> "spaceship" three-way comparison operator as one of the new features that were added to C++20. In the paper titled Consistent comparison Sutter, Maurer and Brown demonstrate the concepts of the new design. For an overview of the proposal, here's an excerpt from the article:
The expression a <=> b returns an object that compares <0 if a < b, compares >0 if a > b, and compares ==0 if a and b are equal/equivalent.
Common case: To write all comparisons for your type X with type Y, with memberwise semantics, just write:
auto X::operator<=>(const Y&) =default;Advanced cases: To write all comparisons for your type X with type Y, just write operator<=> that takes a Y, can use =default to get memberwise semantics if desired, and returns the appropriate category type:
- Return an _ordering if your type naturally supports <, and we’ll efficiently generate symmetric <, >, <=, >=, ==, and !=; otherwise return an _equality, and we’ll efficiently generate symmetric == and !=.
- Return strong_ if for your type a == b implies f(a) == f(b) (substitutability, where f reads only comparison-salient state that is accessible using the public const members), otherwise return weak_.
Comparison Categories
Five comparison categories are defined as std:: types, each having the following predefined values:
+--------------------------------------------------------------------+
| | Numeric values | Non-numeric |
| Category +-----------------------------------+ |
| | -1 | 0 | +1 | values |
+------------------+------+------------+---------------+-------------+
| strong_ordering | less | equal | greater | |
| weak_ordering | less | equivalent | greater | |
| partial_ordering | less | equivalent | greater | unordered |
| strong_equality | | equal | nonequal | |
| weak_equality | | equivalent | nonequivalent | |
+------------------+------+------------+---------------+-------------+
Implicit conversions between these types are defined as follows:
strong_orderingwith values {less,equal,greater} implicitly converts to:weak_orderingwith values {less,equivalent,greater}partial_orderingwith values {less,equivalent,greater}strong_equalitywith values {unequal,equal,unequal}weak_equalitywith values {nonequivalent,equivalent,nonequivalent}
weak_orderingwith values {less,equivalent,greater} implicitly converts to:partial_orderingwith values {less,equivalent,greater}weak_equalitywith values {nonequivalent,equivalent,nonequivalent}
partial_orderingwith values {less,equivalent,greater,unordered} implicitly converts to:weak_equalitywith values {nonequivalent,equivalent,nonequivalent,nonequivalent}
strong_equalitywith values {equal,unequal} implicitly converts to:weak_equalitywith values {equivalent,nonequivalent}
Three-way comparison
The<=>token is introduced. The character sequence<=>tokenizes to<= >, in old source code. For example,X<&Y::operator<=>needs to add a space to retain its meaning.
The overloadable operator<=>is a three-way comparison function and has precedence higher than< and lower than<<. It returns a type that can be compared against literal0but other return types are allowed such as to support expression templates. All<=>operators defined in the language and in the standard library return one of the 5 aforementionedstd::comparison category types.
For language types, the following built-in<=>same-type comparisons are provided. All are constexpr, except where noted otherwise. These comparisons cannot be invoked heterogeneously using scalar promotions/conversions.
- For
bool, integral, and pointer types,<=>returnsstrong_ordering. - For pointer types, the different cv-qualifications and derived-to-base conversions are allowed to invoke a homogeneous built-in
<=>, and there are built-in heterogeneousoperator<=>(T*, nullptr_t). Only comparisons of pointers to the same object/allocation are constant expressions. - For fundamental floating point types,
<=>returnspartial_ordering, and can be invoked heterogeneously by widening arguments to a larger floating point type. - For enumerations,
<=>returns the same as the enumeration's underlying type's<=>. - For
nullptr_t,<=>returnsstrong_orderingand always yieldsequal. - For copyable arrays,
T[N] <=> T[N]returns the same type asT's<=>and performs lexicographical elementwise comparison. There is no<=>for other arrays. - For
voidthere is no<=>.
To better understand the inner workings of this operator, please read the original paper. This is just what I've found out using search engines.
回答3:
This answer has become irrelevant since the referenced web page has changed
The web page you are referencing was broken. It was being edited a lot that day and different parts was not in sync. The status when I was looking at it was:
At the top of the page it lists the currently existing comparison operators (in C++14). There is no <=>there.
At the bottom of the page, they should have listed the same operators, but they goofed and added this future suggestion.
gcc doesn't know about <=>yet (and with -std=c++14, never will), so
it thinks you meant a <= > b. This is explains the error message.
If you try the same thing five years from now you will probably get a better error message, something like <=> not part of C++14.
来源:https://stackoverflow.com/questions/47466358/what-is-the-operator-in-c