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

44

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 les conteneurs tels que std::unordered_map::operator!=et std::unordered_set::operator!=seront supprimés en C ++ 20 selon cppreference.

Le fait d'écrire if(!(id1 == id2))ne rend pas le code plus clair que if(id1 != id2), au contraire, tout le contraire ...

Aconcagua
la source

Réponses:

62

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 fournissez seulement operator==, alors a != best réécrit !(a == b).

Depuis [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.

Pour operator!=autant que je sache, tous les conteneurs ont été retirés (voir par exemple le synopsis des vecteurs ). Les seules exceptions sont les adaptateurs de conteneurs std::queueet 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.

N. Shead
la source
7
p1614 peut également être intéressant, car je pense que c'est la proposition qui a supprimé les surcharges.
N. Shead
39

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

[over.match.oper]

3 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 opérande droit d'un type dont cv- la version non qualifiée 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:

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

std::type_infoet de nombreux autres types de bibliothèques ont été operator!=supprimés dans le cadre de P1614 - The Mothership has Landed .

Conteur - Unslander Monica
la source