web-dev-qa-db-fra.com

Pourquoi operator! = Est-il supprimé en C ++ 20 pour de nombreux types de bibliothèques standard?

Selon cppreference , std::type_info::operator!= Est supprimé avec C++ 20, cependant, std::type_info::operator== Reste apparemment.

Quel est le raisonnement derrière? Je pourrais être d'accord pour comparer l'inégalité comme étant dénuée de sens, mais alors comparer pour l'égalité serait tout aussi insignifiant, non?

De même, operator!= De nombreux autres types de bibliothèques standard, y compris des conteneurs tels que std::unordered_map::operator!= et std::unordered_set::operator!= seront supprimés dans C++ 20 selon la référence cpp.

Devoir écrire if(!(id1 == id2)) ne rend pas le code plus clair que if(id1 != id2), au contraire, juste le contraire ...

43
Aconcagua

En C++ 20, le fonctionnement des opérateurs relationnels a été modifié, notamment avec l'introduction de l'opérateur de vaisseau spatial <=>. En particulier, si vous ne fournissez que operator==, Alors a != b Est réécrit dans !(a == b).

De [over.match.oper] /3.4 :

L'ensemble de candidats réécrit est déterminé comme suit:

  • Pour les opérateurs relationnels ([expr.rel]), les candidats réécrits incluent tous les candidats non réécrits pour l'expression x <=> y.
  • Pour les opérateurs relationnels ([expr.rel]) et de comparaison à trois ([expr.spaceship]), les candidats réécrits incluent également un candidat synthétisé, avec l'ordre des deux paramètres inversé, pour chaque candidat non réécrit pour le expression y <=> x.
  • Pour l'opérateur! = ([Expr.eq]), les candidats réécrits incluent tous les candidats non réécrits pour l'expression x == y.
  • Pour les opérateurs d'égalité, les candidats réécrits incluent également un candidat synthétisé, avec l'ordre des deux paramètres inversé, pour chaque candidat non réécrit pour l'expression y == x.
  • Pour tous les autres opérateurs, l'ensemble de candidats réécrit est vide.

Et [over.match.oper]/9 :

Si un candidat opérateur == réécrit est sélectionné par résolution de surcharge pour un opérateur @, son type de retour doit être cv bool, et x @ y est interprété comme:

  • si @ est! = et que le candidat sélectionné est un candidat synthétisé avec un ordre de paramètres inversé,! (y == x),
  • sinon, si @ est! =,! (x == y) ,
  • sinon (quand @ est ==), y == x,

dans chaque cas en utilisant l'opérateur réécrit sélectionné == candidat.

En tant que tel, une surcharge explicite pour operator!= N'est plus nécessaire. La suppression de l'opérateur n'a pas modifié la sémantique de comparaison.

Tous les conteneurs ont vu leur operator!= Supprimé, pour autant que je sache (vérifiez par exemple le synopsis vectoriel ). Les seules exceptions sont les adaptateurs de conteneur std::queue Et std::stack: Je suppose que c'est pour préserver la compatibilité descendante lorsqu'ils sont utilisés avec des conteneurs tiers, au cas où les opérateurs d'égalité ne seraient pas symétriques.

61
N. Shead

Nous n'avons pas besoin d'une bibliothèque fournie operator!= plus. Fournir operator== permet au compilateur de jongler et d'évaluer a != b en terme de a == b, tout seul.

[over.match.oper]

Pour un opérateur unaire @ avec un opérande d'un type dont la version non qualifiée cv est T1, et pour un opérateur binaire @ avec un opérande gauche d'un type dont la version non qualifiée cv est T1 et un droit l'opérande d'un type dont la version non qualifiée de cv est T2, quatre ensembles de fonctions candidates, candidats membres désignés, candidats non membres, candidats intégrés et candidats réécrits, sont construits comme suit:

.4. Pour l'opérateur! = ([Expr.eq]), les candidats réécrits incluent tous les candidats non réécrits pour l'expression x == y.

std::type_info et de nombreux autres types de bibliothèques avaient leur operator!= supprimé dans le cadre de P1614 - Le vaisseau-mère a atterri .