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_ordering
avec des valeurs { less
, equal
, greater
} convertit implicitement:
weak_ordering
avec des valeurs { less
, equivalent
, greater
}
partial_ordering
avec des valeurs { less
, equivalent
, greater
}
strong_equality
avec des valeurs { unequal
, equal
, unequal
}
weak_equality
avec des valeurs { nonequivalent
, equivalent
, nonequivalent
}
weak_ordering
avec des valeurs { less
, equivalent
, greater
} convertit implicitement:
partial_ordering
avec des valeurs { less
, equivalent
, greater
}
weak_equality
avec des valeurs { nonequivalent
, equivalent
, nonequivalent
}
partial_ordering
avec des valeurs { less
, equivalent
, greater
, unordered
} convertit implicitement:
weak_equality
avec des valeurs { nonequivalent
, equivalent
, nonequivalent
, nonequivalent
}
strong_equality
avec des valeurs { equal
, unequal
} convertit implicitement en:
weak_equality
avec 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, 0
mais 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
bool
types, 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_ordering
et 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_ordering
et 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
void
il 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.