¿Por qué se elimina operator! = En C ++ 20 para muchos tipos de biblioteca estándar?

44

Según cppreference , std::type_info::operator!=se elimina con C ++ 20, sin embargo, std::type_info::operator==aparentemente permanece.

¿Cuál es el razonamiento detrás? Podría estar de acuerdo en que la comparación de la desigualdad no tenga sentido, pero luego la comparación de la igualdad tampoco tendría sentido, ¿no?

De manera similar, operator!=de muchos otros tipos de bibliotecas estándar, incluidos contenedores como std::unordered_map::operator!=y std::unordered_set::operator!=se eliminarán en C ++ 20 de acuerdo con cppreference.

Tener que escribir if(!(id1 == id2))no aclara ningún código en comparación con if(id1 != id2), por el contrario, todo lo contrario ...

Aconcagua
fuente

Respuestas:

62

En C ++ 20, la forma en que funcionan los operadores relacionales cambió, especialmente con la introducción del <=>operador de la nave espacial . En particular, si solo proporciona operator==, a != bse reescribe a !(a == b).

De [over.match.oper] /3.4 :

El conjunto de candidatos reescrito se determina de la siguiente manera:

  • Para los operadores relacionales ([expr.rel]), los candidatos reescritos incluyen todos los candidatos no reescritos para la expresión x <=> y.
  • Para los operadores relacionales ([expr.rel]) y de comparación de tres vías ([expr.spaceship]), los candidatos reescritos también incluyen un candidato sintetizado, con el orden de los dos parámetros invertidos, para cada candidato no reescrito para el expresión y <=> x.
  • Para el operador! = ([Expr.eq]), los candidatos reescritos incluyen todos los candidatos no reescritos para la expresión x == y.
  • Para los operadores de igualdad, los candidatos reescritos también incluyen un candidato sintetizado, con el orden de los dos parámetros invertidos, para cada candidato no reescrito para la expresión y == x.
  • Para todos los demás operadores, el conjunto de candidatos reescrito está vacío.

Y [over.match.oper] / 9 :

Si se selecciona un operador reescrito == candidato por resolución de sobrecarga para un operador @, su tipo de retorno será cv bool, y x @ y se interpreta como:

  • if @ is! = y el candidato seleccionado es un candidato sintetizado con un orden inverso de parámetros,! (y == x),
  • de lo contrario, si @ es! =,! (x == y) ,
  • de lo contrario (cuando @ es ==), y == x,

en cada caso utilizando el operador reescrito seleccionado == candidato.

Como tal, operator!=ya no es necesaria una sobrecarga explícita para . La eliminación del operador no ha cambiado la semántica de comparación.

Todos los contenedores se han operator!=eliminado, por lo que puedo ver (ver, por ejemplo, la sinopsis del vector ). Las únicas excepciones son los adaptadores de contenedor std::queuey std::stack: supongo que es para preservar la compatibilidad con versiones anteriores cuando se usa con contenedores de terceros, en caso de que los operadores de igualdad no sean simétricos.

N. Shead
fuente
77
p1614 también puede ser de interés, ya que creo que esa fue la propuesta que eliminó las sobrecargas.
N. Shead
39

Ya no necesitamos una biblioteca provista operator!=. Proporcionar operator==permite al compilador hacer algunos malabarismos y evaluar a != ben términos de a == btodo por sí mismo.

[over.match.oper]

3 Para un operador unario @ con un operando de un tipo cuya versión no calificada cv es T1, y para un operador binario @ con un operando izquierdo de un tipo cuya versión no calificada cv es T1 y un operando derecho de un tipo cuyo cv- la versión no calificada es T2, cuatro conjuntos de funciones candidatas, candidatos miembros designados, candidatos no miembros, candidatos incorporados y candidatos reescritos, se construyen de la siguiente manera:

3.4.3 Para el operador! = ([Expr.eq]), los candidatos reescritos incluyen todos los candidatos no reescritos para la expresión x == y.

std::type_infoy muchos más tipos de bibliotecas se operator!=eliminaron como parte de P1614: The Mothership ha aterrizado .

StoryTeller - Unslander Monica
fuente