web-dev-qa-db-fra.com

Qu'est-ce que l'opérateur <=> en C ++?

Alors que j'essayais de connaître les opérateurs C++ , je suis tombé sur un étrange opérateur de comparaison sur cppreference.com ,* dans un tableau qui ressemblait à ceci:

enter image description here

"Bien, si ce sont des opérateurs communs en C++, je ferais mieux de les apprendre", pensai-je. Mais toutes mes tentatives pour élucider ce mystère ont été infructueuses. Même ici, sur Stack Overflow, je n'ai pas eu de chance dans mes recherches.

Y a-t-il un lien entre <=> et C++ ?

Et s'il y en a un, que fait exactement cet opérateur?

* En attendant, cppreference.com a mis à jour cette page et contient désormais des informations sur l'opérateur<=>.

196
q-l-p

Le 2017-11-11 , le comité ISO C++ a adopté la proposition de Herb Sutter pour le <=> "vaisseau spatial" trois- l’opérateur de comparaison de voies parmi les nouvelles fonctionnalités ajoutées à C++ 20 . Dans le document intitulé Comparaison cohérente , Sutter, Maurer et Brown illustrent 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 commun: Pour écrire toutes les comparaisons pour votre type X avec tapez Y, avec la sémantique membre par membre, écrivez simplement:

auto X::operator<=>(const Y&) =default;

Cas avancés: Pour écrire toutes les comparaisons pour votre type X avec tapez Y, écrivez simplement l'opérateur <=> qui prend un Y, peut utiliser = default pour obtenir une sémantique membre par membre si désiré et retourne le type de catégorie approprié:

  • Retourne un _ ordering si votre type supporte naturellement <, et nous générer efficacement symétrique <, > , <= , > = , == , et ! = ; sinon, retourne une _ égalité , et nous générerons efficacement des symétriques == et ! = .
  • Retour fort _ si pour votre type a == b implique f (a) == f (b) (substituabilité, où f ne lit que état comparatif saillant accessible à l'aide des membres public const ), sinon renvoie faible _ .

Catégories de comparaison

Cinq catégories de comparaison sont définies en tant que types std::, 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 les valeurs {less, equal, greater} convertit implicitement en:
    • weak_ordering avec les valeurs {less, equivalent, greater}
    • partial_ordering avec les valeurs {less, equivalent, greater}
    • strong_equality avec les valeurs {unequal, equal, unequal}
    • weak_equality avec les valeurs {nonequivalent, equivalent, nonequivalent}
  • weak_ordering avec les valeurs {less, equivalent, greater} convertit implicitement en:
    • partial_ordering avec les valeurs {less, equivalent, greater}
    • weak_equality avec les valeurs {nonequivalent, equivalent, nonequivalent}
  • partial_ordering avec les valeurs {less, equivalent, greater, unordered} convertit implicitement en:
    • weak_equality avec les valeurs {nonequivalent, equivalent, nonequivalent, nonequivalent}
  • strong_equality avec les valeurs {equal, unequal} convertit implicitement en:
    • weak_equality avec les valeurs {equivalent, nonequivalent}

Comparaison à trois

Le<=>token est introduit. La séquence de caractères<=> permet de former<= >, 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 retourne un type qui peut être comparé à literal0 mais d'autres types de retour sont autorisés, par exemple pour prendre en charge les modèles d'expression. Tous les opérateurs<=> définis dans le langage et dans la bibliothèque standard renvoient l’un des 5 types de catégories de std::comparaison susmentionnés.

Pour les types de langue, les comparaisons intégrées __<=>same-type suivantes sont fournies. Tous sont constexpr , sauf indication contraire. Ces comparaisons ne peuvent pas être appelées de manière hétérogène à l'aide de promotions/conversions scalaires.

  • Pourbool, types intégral et pointeur, <=>returnsstrong_ordering.
  • Pour les types de pointeur, les différentes qualifications cv et les conversions dérivées à la base sont autorisées à appeler un<=> intégré homogène, et il existe des _operator<=>(T*, nullptr_t) hétérogènes intégrées. Seules les comparaisons de pointeurs sur le même objet/allocation sont des expressions constantes.
  • <=> renvoiepartial_ordering et peut être invoqué de manière hétérogène en élargissant les arguments à un type de virgule flottante plus grand.
  • Pour les énumérations, <=> renvoie la même chose que le type<=> du type sous-jacent de l'énumération.
  • Pournullptr_t, <=> renvoiestrong_orderinget donne toujoursequal.
  • Pour les tableaux copiables, T[N] <=> T[N] renvoie le même type queT 's<=>et effectue une comparaison lexicographique élément par élément. Il n'y a pas<=>pour d'autres tableaux.
  • Pourvoidil n'y a pas<=>.

Pour mieux comprendre le fonctionnement interne de cet opérateur, veuillez lire l'original paper . C'est ce que j'ai découvert grâce aux moteurs de recherche.

108
q-l-p

C'est ce qu'on appelle l'opérateur à trois voies de comparaison .

Selon la proposition de papier P0515 :

Il y a un nouvel opérateur de comparaison à trois voies, <=>. 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.

Pour écrire toutes les comparaisons pour votre type, écrivez simplement operator<=> qui renvoie le type de catégorie approprié:

  • Retourne un _ordering si votre type supporte naturellement <, et nous générerons efficacement <, >, <=, >=, == et !=; sinon, retourne une _equality , et nous générerons efficacement == et ! = .

  • Renvoie fort si, pour votre type, a == b implique f(a) == f(b) (substituabilité, où f lit uniquement l'état de comparaison essentiel accessible à l'aide de l'interface const non privée), sinon renvoie faible.

Le cppreference dit:

Les expressions de l'opérateur de comparaison à trois voies ont la forme

lhs <=> rhs   (1)  

L'expression retourne un objet qui

  • compare <0 si lhs < rhs
  • compare >0 si lhs > rhs
  • et compare ==0 si lhs et rhs sont égaux/équivalents.
167
msc

Cette réponse est devenue sans objet depuis que la page Web référencée a changé

Le page Web que vous référencez était cassé. Il était en train d'être édité beaucoup ce jour-là et différentes parties n'étaient pas synchronisées. Le statut quand je regardais c'était:

En haut de la page, il répertorie les opérateurs de comparaison existants (en C++ 14). Il n'y a pas de <=>there.

Au bas de la page, ils auraient dû répertorier les mêmes opérateurs, mais ils ont fait une gaffe et ajouté cette suggestion future.

gcc ne sait pas que <=>yet (et avec -std=c++14 ne le fera jamais), il pense donc que vous vouliez dire a <= > b. Ceci explique le message d'erreur.

Si vous essayez la même chose dans cinq ans, vous obtiendrez probablement un meilleur message d'erreur, quelque chose comme <=> not part of C++14.

11
Stig Hemmer