58 votes

En quoi l'opérateur de comparaison à trois voies est-il différent de la soustraction?

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.

58voto

dasblinkenlight Points 264350

L'opérateur permet de résoudre le problème avec dépassement numérique que vous obtenez avec la soustraction: si vous soustraire un grand nombre positif à partir d'un négatif qui est proche, INT_MIN, vous obtenez un nombre qui ne peut pas être représenté comme une int, provoquant ainsi un comportement indéfini.

Bien que la version 3 est libre de ce problème, il manque totalement de lisibilité: il faudra un certain temps pour comprendre par quelqu'un qui n'a jamais vu ce truc avant. <=> opérateur résout le problème de lisibilité, trop.

Ce n'est qu'un problème traité par le nouvel opérateur. La Section 2.2.3 de Herb Sutter de la comparaison de papier parle de l'utilisation de <=> avec d'autres types de données de la langue où la soustraction peut produire des résultats incohérents.

43voto

Oli Charlesworth Points 148744

Voici quelques cas que la soustraction de ne pas travailler pour:

  1. unsigned types.
  2. Opérandes cause de dépassement d'entier.
  3. Types définis par l'utilisateur qui ne définissent pas operator - (peut-être parce que ce n'est pas significative, 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 venir avec des solutions de contournement pour au moins #1 et #2. Mais l'intention de l' operator <=> d'encapsuler que la laideur.

18voto

Cris Luengo Points 22016

Il y a des réponses ici sur la différence, mais Herb Sutter dans son papier spécifiquement dit:

<=> est de type maîtres d'œuvre: le code de l'Utilisateur (y compris le code générique) en dehors de la mise en œuvre d'un opérateur<=> devrait presque jamais invoquer un <=> directement (comme déjà découvert comme une bonne pratique dans d'autres langues);

Donc, même si il n'y a pas de différence, du point de l'opérateur est différent: à l'aide de la classe des écrivains de générer des opérateurs de comparaison.

La principale différence entre l'opérateur de soustraction et le "vaisseau spatial" de l'opérateur (en fonction de Sutter proposition) est que la surcharge operator- vous donne un opérateur de soustraction, alors que la surcharge operator<=>:

  • vous donne les 6 de base des opérateurs de comparaison (même si vous déclarez l'opérateur default: aucun code n'est à écrire!);
  • déclare si votre classe est comparable, est triable, et si l'ordre est total ou partiel (forts/faibles de Sutter proposition);
  • permet hétérogène des comparaisons: vous pouvez la surcharge de comparer votre classe à n'importe quel autre type.

D'autres types de différences dans la valeur de retour: operator<=> serait de retour d'un enum d'une classe, la classe spécifie si le type est sortable et si le tri est fort ou faible. La valeur de retour serait de convertir -1, 0 ou 1 (si Sutter laisse de la place pour le type de retour aussi à indiquer la distance, comme strcmp t). En tout cas, en supposant que le -1, 0, 1 valeur de retour, nous allons obtenir enfin un vrai signum fonction en C++! (signum(x) == x<=>0)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X