operaciones - operadores relacionales en c++
¿Cuál es el operador<=> en C++? (3)
El 2017-11-11 , 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 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 de comparación relevante 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::
types, 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_ordering
con valores {less
,equal
,strong_ordering
} se convierte implícitamente en:-
weak_ordering
con valores {less
,equivalent
,greater
} -
partial_ordering
con valores {less
,equivalent
,greater
} -
strong_equality
con valores {unequal
,equal
,unequal
} -
weak_equality
con valores {nonequivalent
,equivalent
,nonequivalent
}
-
-
weak_ordering
con valores {less
,equivalent
,greater
} se convierte implícitamente en:-
partial_ordering
con valores {less
,equivalent
,greater
} -
weak_equality
con valores {nonequivalent
,equivalent
,nonequivalent
}
-
-
partial_ordering
con valores {less
,equivalent
,greater
,unordered
} se convierte implícitamente en:-
weak_equality
con valores {nonequivalent
,equivalent
,nonequivalent
,nonequivalent
}
-
-
strong_equality
con valores {equal
,unequal
} se convierte implícitamente en:-
weak_equality
con valores {equivalent
, noequivalent
}
-
Comparación de tres vías
Se introduce el token
<=>
.
La secuencia de caracteres
<=>
tokeniza a
<=>
, 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 una prioridad mayor que
<
y menor que
<<
.
Devuelve un tipo que se puede comparar con el literal
0
pero 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 tipos de categorías de comparación
std::
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.
-
Para los tipos
bool
, integral y de puntero,<=>
devuelvestrong_ordering
. -
Para los tipos de puntero, las diferentes calificaciones de cv y las conversiones derivadas a base pueden invocar un
<=>
incorporado homogéneo, y hay unoperator<=>(T*, nullptr_t)
heterogéneo incorporado<=>
operator<=>(T*, nullptr_t)
. Solo las comparaciones de punteros al mismo objeto / asignación son expresiones constantes. -
Para los tipos de coma flotante fundamentales,
<=>
devuelve la ordenpartial_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 el tipo subyacente de la enumeración<=>
. -
Para
nullptr_t
,<=>
devuelvestrong_ordering
y siempre produceequal
. -
Para matrices copiables,
T[N] <=> T[N]
devuelve el mismo tipo queT
''s<=>
y realiza una comparación lexicográfica por elementos. No hay<=>
para otras matrices. -
Para
void
no hay<=>
.
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.
Mientras intentaba aprender sobre los operadores de C ++ , me topé con un operador de comparación extraño en cppreference.com , * en una tabla que se veía así:
"Bueno, si estos son operadores comunes en C ++, será mejor que los aprenda", pensé. Pero todos mis intentos de dilucidar este misterio no tuvieron éxito. Incluso aquí, en Stack Overflow, no tuve suerte en mi búsqueda.
¿Hay alguna conexión entre <=> y C ++ ?
Y si lo hay, ¿qué hace exactamente este operador?
* Mientras tanto, cppreference.com actualizó esa página y ahora contiene información sobre el operador
<=>
.
Esto se llama el operador de comparación de tres vías .
De acuerdo con la propuesta de papel P0515 :
Hay un nuevo operador de comparación de tres vías,
<=>
. La expresióna <=> b
devuelve un objeto que compara<0
sia < b
, compara>0
sia > b
, y compara==0
sia
yb
son iguales / equivalentes.Para escribir todas las comparaciones para su tipo, simplemente escriba el
operator<=>
que devuelve el tipo de categoría apropiado:
Devuelva un _orden si su tipo admite naturalmente
<
, y generaremos eficientemente<
,>
,<=
,>=
,==
, y!=
; de lo contrario, devolverá una _equality , y generaremos eficientemente == y ! = .Regrese fuerte si para su tipo
a == b
implicaf(a) == f(b)
(sustituibilidad, donde f lee solo el estado relevante de comparación accesible usando la interfaz const no privada), de lo contrario, devuelve débil.
La cppreference.com dice:
Las expresiones de operador de comparación de tres vías tienen la forma
lhs <=> rhs (1)
La expresión devuelve un objeto que
- compara
<0
silhs < rhs
- compara
>0
silhs > rhs
- y compara
==0
silhs
yrhs
son iguales / equivalentes.
Esta respuesta se ha vuelto irrelevante desde que la página web referenciada ha cambiado
La cppreference.com estaba rota. Se estaba editando mucho ese día y las diferentes partes no estaban sincronizadas. El estado cuando lo miraba era:
En la parte superior de la página, enumera los operadores de comparación existentes actualmente (en C ++ 14).
No hay
<=>
allí.
Al final de la página, deberían haber enumerado los mismos operadores, pero se burlaron y agregaron esta sugerencia futura.
gcc
aún no sabe acerca de
<=>
(y con
-std=c++14
, nunca lo sabrá), por lo que cree que se refería a a
<=>
a <= > b
.
Esto explica el mensaje de error.
Si intenta lo mismo dentro de cinco años, probablemente obtendrá un mejor mensaje de error, algo como
<=> not part of C++14.