cpp/language/default comparisons

Provides a way to request the compiler to generate consistent comparison operators for a class.

Explanation
@1@ Declare the defaulted comparison function as a member function. @2@ Declare the defaulted comparison function as a non-member function. @3@ Declare the defaulted comparison function as a non-member function. Arguments are passed by value.

The three-way comparison function (whether defaulted or not) is called whenever values are compared using, , , , or and overload resolution selects this overload.

The equality comparison function (whether defaulted or not) is called whenever values are compared using or  and overload resolution selects this overload.

Like defaulted special member functions, a defaulted comparison function is defined if or.

Defaulted three-way comparison
The default performs lexicographical comparison by successively comparing the base (left-to-right depth-first) and then non-static member (in declaration order) subobjects of  to compute, recursively expanding array members (in order of increasing subscript), and stopping early when a not-equal result is found, that is:

It is unspecified whether virtual base subobjects are compared more than once.

If the declared return type is, then the actual return type is the common comparison category of the base and member subobject and member array elements to be compared (see ). This makes it easier to write cases where the return type non-trivially depends on the members, such as:

Let be the return type, each pair of subobjects,  is compared as follows:


 * If is usable and can be explicitly converted to  using, the result of comparison is.
 * Otherwise, if overload resolution for is performed and finds at least one viable candidate, the comparison is not defined ( is defined as deleted).
 * Otherwise, if is not a comparison category type (see below), or either  or  is not usable, the comparison is not defined ( is defined as deleted).
 * Otherwise, if is, the result is


 * Otherwise, if is, the result is


 * Otherwise ( is ), the result is

Per the rules for any overload, a defaulted  overload will also allow the type to be compared with, , , and.

If is defaulted and  is not declared at all, then  is implicitly defaulted.

Defaulted equality comparison
A class can define as defaulted, with a return value of. This will generate an equality comparison of each base class and member subobject, in their declaration order. Two objects are equal if the values of their base classes and members are equal. The test will short-circuit if an inequality is found in members or base classes earlier in declaration order.

Per the rules for, this will also allow inequality testing:

Other defaulted comparison operators
Any of the four relational operators can be explicitly defaulted. A defaulted relational operator must have the return type.

Such operator will be deleted if overload resolution over (considering also  with reversed order of parameters) fails, or if this  is not applicable to the result of that. Otherwise, the defaulted calls  if an  with the original order of parameters was selected by overload resolution, or  otherwise:

Similarly, can be defaulted. It is deleted if overload resolution over (considering also  with reversed order of parameters) fails, or if the result of  does not have type. The defaulted calls  or  as selected by overload resolution.

Defaulting the relational operators can be useful in order to create functions whose addresses may be taken. For other uses, it is sufficient to provide only and.

Custom comparisons and comparison categories
When the default semantics are not suitable, such as when the members must be compared out of order, or must use a comparison that's different from their natural comparison, then the programmer can write and let the compiler generate the appropriate two-way comparison operators. The kind of two-way comparison operators generated depends on the return type of the user-defined.

There are three available return types:

Strong ordering
An example of a custom that returns  is an operator that compares every member of a class, except in order that is different from the default (here: last name first).

Note: an operator that returns a should compare every member, because if any member is left out, substitutability can be compromised: it becomes possible to distinguish two values that compare equal.

Weak ordering
An example of a custom that returns  is an operator that compares string members of a class in case-insensitive manner: this is different from the default comparison (so a custom operator is required) and it is possible to distinguish two strings that compare equal under this comparison:

Note that this example demonstrates the effect a heterogeneous has: it generates heterogeneous comparisons in both directions.

Partial ordering
Partial ordering is an ordering that allows incomparable (unordered) values, such as NaN values in floating-point ordering, or, in this example, persons that are not related: