El 11-11-2017 , el comité ISO C ++ adoptó la propuesta de Herb Sutter para el operador de comparación de tres vías <=> "nave espacial" como una de las nuevas características que se agregaron a C ++ 20 . En el artículo titulado Comparación consistente Sutter, Maurer y Brown demuestran los conceptos del nuevo diseño. Para obtener una descripción general de la propuesta, aquí hay un extracto del artículo:
La expresión a <=> b devuelve un objeto que compara <0 si a <b , compara > 0 si a> b , y compara == 0 si a y b son iguales / equivalentes.
Caso común: para escribir todas las comparaciones para su tipo X con el tipo Y , con la semántica de miembro, simplemente escriba:
auto X::operator<=>(const Y&) =default;
Casos avanzados: para escribir todas las comparaciones para su tipo X con el tipo Y , simplemente escriba el operador <=> que toma una Y , puede usar
= default para obtener la semántica de miembro si lo desea, y devuelve el tipo de categoría apropiado:
- Devuelva una orden si su tipo admite naturalmente < , y generaremos eficientemente < , > , <= , > = , == y
! = ; de lo contrario, devolverá una _equality y generaremos eficientemente simétrica == y ! = .
- Devuelva strong_ si para su tipo a == b implica f (a) == f (b) (sustituibilidad, donde f lee solo el estado relevante de comparación al que se puede acceder utilizando los miembros de const público ), de lo contrario, devuelve
débil_ .
Categorías de comparación
Cinco categorías de comparación se definen como std::tipos, cada una con los siguientes valores predefinidos:
+--------------------------------------------------------------------+
| | 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 | |
+------------------+------+------------+---------------+-------------+
Las conversiones implícitas entre estos tipos se definen de la siguiente manera:
strong_orderingcon valores { less, equal, greater} convierte implícitamente a:
weak_orderingcon los valores { less, equivalent, greater}
partial_orderingcon los valores { less, equivalent, greater}
strong_equalitycon los valores { unequal, equal, unequal}
weak_equalitycon los valores { nonequivalent, equivalent, nonequivalent}
weak_orderingcon valores { less, equivalent, greater} convierte implícitamente a:
partial_orderingcon los valores { less, equivalent, greater}
weak_equalitycon los valores { nonequivalent, equivalent, nonequivalent}
partial_orderingcon valores { less, equivalent, greater, unordered} convierte implícitamente a:
weak_equalitycon los valores { nonequivalent, equivalent, nonequivalent, nonequivalent}
strong_equalitycon valores { equal, unequal} se convierte implícitamente en:
weak_equalitycon valores { equivalent, nonequivalent}
Comparación de tres vías
Se <=>introduce el token. La secuencia de caracteres se <=>tokeniza <= >en el código fuente anterior. Por ejemplo, X<&Y::operator<=>necesita agregar un espacio para retener su significado.
El operador sobrecargable <=>es una función de comparación de tres vías y tiene prioridad mayor que <y menor que <<. Devuelve un tipo que se puede comparar con el literal, 0pero se permiten otros tipos de retorno, como para admitir plantillas de expresión. Todos los <=>operadores definidos en el idioma y en la biblioteca estándar devuelven uno de los 5 std::tipos de categorías de comparación mencionados anteriormente .
Para los tipos de idioma, se proporcionan las siguientes <=>comparaciones integradas del mismo tipo. Todos son constexpr , excepto donde se indique lo contrario. Estas comparaciones no pueden invocarse heterogéneamente usando promociones / conversiones escalares.
- For
bool, integral y tipos de puntero, <=>devuelve strong_ordering.
- Para los tipos de puntero, las diferentes calificaciones de cv y las conversiones derivadas a base pueden invocar una función integrada homogénea
<=>, y hay funciones heterogéneas integradas operator<=>(T*, nullptr_t). Solo las comparaciones de punteros al mismo objeto / asignación son expresiones constantes.
- Para los tipos de coma flotante fundamentales,
<=>retornos partial_ordering, y se puede invocar de manera heterogénea ampliando los argumentos a un tipo de coma flotante más grande.
- Para las enumeraciones,
<=>devuelve lo mismo que los tipos subyacentes de la enumeración <=>.
- Para
nullptr_t, <=>vuelve strong_orderingy siempre rinde equal.
- Para matrices copiables,
T[N] <=> T[N]devuelve el mismo tipo que T's <=>y realiza una comparación lexicográfica por elementos. No hay <=>para otras matrices.
- Por
voidallí no está <=>.
Para comprender mejor el funcionamiento interno de este operador, lea el documento original . Esto es justo lo que descubrí usando los motores de búsqueda.