Le 11/11/2017 , le comité ISO C ++ a adopté la proposition de Herb Sutter pour l' opérateur de comparaison à trois voies <=> "vaisseau spatial" comme l'une des nouvelles fonctionnalités ajoutées au C ++ 20 . Dans l'article intitulé Comparaison cohérente Sutter, Maurer et Brown démontrent les concepts du nouveau design. Pour un aperçu de la proposition, voici un extrait de l'article:
L'expression a <=> b renvoie un objet qui compare <0 si a <b , compare > 0 si a> b et compare == 0 si a et b sont égaux / équivalents.
Cas courant : pour écrire toutes les comparaisons de votre type X avec le type Y , avec la sémantique des membres, écrivez simplement:
auto X::operator<=>(const Y&) =default;
Cas avancés: pour écrire toutes les comparaisons de votre type X avec le type Y , il suffit d'écrire l' opérateur <=> qui prend un Y , peut utiliser
= default pour obtenir la sémantique des membres si vous le souhaitez et retourne le type de catégorie approprié:
- Retour un _ordering si votre type supports naturellement < , et nous allons générer efficacement symétrique < , > , <= , > = , == et
! = ; sinon retournez une _equality , et nous générerons efficacement symétrique == et ! = .
- Renvoie strong_ si pour votre type, a == b implique f (a) == f (b) (substituabilité, où f ne lit que l'état de comparaison qui est accessible à l'aide des membres const publics ), sinon retour
faible_ .
Catégories de comparaison
Cinq catégories de comparaison sont définies en tant que std::types, chacune ayant les valeurs prédéfinies suivantes:
+--------------------------------------------------------------------+
| | 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 | |
+------------------+------+------------+---------------+-------------+
Les conversions implicites entre ces types sont définies comme suit:
strong_orderingavec des valeurs { less, equal, greater} convertit implicitement:
weak_orderingavec des valeurs { less, equivalent, greater}
partial_orderingavec des valeurs { less, equivalent, greater}
strong_equalityavec des valeurs { unequal, equal, unequal}
weak_equalityavec des valeurs { nonequivalent, equivalent, nonequivalent}
weak_orderingavec des valeurs { less, equivalent, greater} convertit implicitement:
partial_orderingavec des valeurs { less, equivalent, greater}
weak_equalityavec des valeurs { nonequivalent, equivalent, nonequivalent}
partial_orderingavec des valeurs { less, equivalent, greater, unordered} convertit implicitement:
weak_equalityavec des valeurs { nonequivalent, equivalent, nonequivalent, nonequivalent}
strong_equalityavec des valeurs { equal, unequal} convertit implicitement en:
weak_equalityavec des valeurs { equivalent, nonequivalent}
Comparaison à trois
Le <=>jeton est introduit. La séquence de caractères est <=>symbolisée par <= >, dans l'ancien code source. Par exemple, X<&Y::operator<=>doit ajouter un espace pour conserver sa signification.
L'opérateur surchargeable <=>est une fonction de comparaison à trois voies et a une priorité supérieure <et inférieure à <<. Il renvoie un type qui peut être comparé à un littéral, 0mais d'autres types de retour sont autorisés, tels que les modèles d'expression. Tous les <=>opérateurs définis dans la langue et dans la bibliothèque standard renvoient l'un des 5 std::types de catégories de comparaison susmentionnés .
Pour les types de langue, les <=>comparaisons intégrées de même type suivantes sont fournies. Tous sont constexpr , sauf indication contraire. Ces comparaisons ne peuvent pas être invoquées de manière hétérogène à l'aide de promotions / conversions scalaires.
- Pour les
booltypes, intégral et pointeur, <=>renvoie strong_ordering.
- Pour les types de pointeurs, les différentes qualifications cv et les conversions dérivées en base sont autorisées à invoquer un intégré homogène
<=>, et il existe des hétérogènes intégrés operator<=>(T*, nullptr_t). Seules les comparaisons de pointeurs vers le même objet / allocation sont des expressions constantes.
- Pour les types à virgule flottante fondamentaux,
<=>renvoie partial_orderinget peut être invoqué de manière hétérogène en élargissant les arguments à un type à virgule flottante plus grand.
- Pour les énumérations,
<=>renvoie la même chose que le type sous-jacent de l'énumération <=>.
- Car
nullptr_t, <=>retourne strong_orderinget rapporte toujours equal.
- Pour les tableaux copiables,
T[N] <=> T[N]renvoie le même type que T's <=>et effectue une comparaison lexicographique élément par élément. Il n'y en a pas <=>pour les autres tableaux.
- Car
voidil n'y en a pas <=>.
Pour mieux comprendre le fonctionnement interne de cet opérateur, veuillez lire le document original . C'est exactement ce que j'ai découvert en utilisant les moteurs de recherche.