Il y a un nouvel opérateur de comparaison <=>
en C++ 20. Cependant, je pense que dans la plupart des cas, une simple soustraction fonctionne bien:
int my_strcmp(const char *a, const char *b) {
while (*a == *b && *a != 0 && *b != 0) {
a++, b++;
}
// Version 1
return *a - *b;
// Version 2
return *a <=> *b;
// Version 3
return ((*a > *b) - (*a < *b));
}
Ils ont le même effet. Je ne peux pas vraiment comprendre la différence.
L’opérateur résout le problème de dépassement numérique que vous obtenez avec la soustraction: si vous soustrayez un grand nombre positif d’un négatif qui est proche de INT_MIN
, vous obtenez un nombre qui ne peut pas être représenté par un int
, ce qui provoque un comportement indéfini.
Bien que la version 3 soit exempte de ce problème, elle manque totalement de lisibilité: il faudrait un certain temps pour la comprendre de la part de quelqu'un qui n'a jamais vu cette astuce auparavant. <=>
l'opérateur résout également le problème de lisibilité.
Ce n'est qu'un problème abordé par le nouvel opérateur. La section 2.2.3 de Herb Sutter's Comparaison cohérente papier parle de l'utilisation de <=>
avec d'autres types de données du langage où la soustraction peut produire des résultats incohérents.
Voici quelques cas pour lesquels la soustraction ne fonctionnera pas:
unsigned
types.operator -
_ (peut-être parce que cela n’a pas de sens - on peut définir un ordre sans définir une notion de distance).Je soupçonne que cette liste est non exhaustive.
Bien sûr, on peut trouver des solutions de contournement pour les n ° 1 et n ° 2 au moins. Mais l'intention de operator <=>
est d’encapsuler cette laideur.
Il y a quelques réponses significatives ici sur la différence, mais Herb Sutter dans son article dit spécifiquement:
<=> est destiné aux personnes qui implémentent le type: le code utilisateur (y compris le code générique) en dehors de la mise en oeuvre d'un opérateur <=> ne devrait presque jamais invoquer un <=> directement (comme cela a déjà été découvert comme une bonne pratique dans d'autres langues);
Donc, même s'il n'y avait pas de différence, le point de l'opérateur est différent: aider les rédacteurs de classe à générer des opérateurs de comparaison.
La différence fondamentale entre l'opérateur de soustraction et l'opérateur "vaisseau spatial" (selon la proposition de Sutter) est que la surcharge operator-
Vous donne un opérateur de soustraction, alors que la surcharge operator<=>
:
default
: pas de code à écrire!);Les autres différences sont dans la valeur de retour: operator<=>
Renverrait un enum
d'une classe. La classe spécifie si le type est triable et si le tri est fort ou faible. La valeur de retour serait convertie en -1, 0 ou 1 (bien que Sutter laisse de la place au type de retour pour indiquer également la distance, comme le fait strcmp
.). Dans tous les cas, en supposant que la valeur de retour soit -1, 0, 1, nous aurons finalement ne vraie fonction de signum en C++ ! (signum(x) == x<=>0
)