Pendant que j'essayais d'en savoir plus sur les opérateurs C ++ , je suis tombé sur un étrange opérateur de comparaison sur cppreference.com , * dans un tableau qui ressemblait à ceci:
"Eh 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 échoué. Même ici, sur Stack Overflow, je n'ai pas eu de chance dans ma recherche.
Existe-t-il une connexion entre <=> et C ++ ?
Et s'il y en a un, que fait exactement cet opérateur?
* Entre-temps, cppreference.com a mis à jour cette page et contient maintenant des informations sur l' <=>
opérateur.
bar< foo::operator<=>
est un exemple de la façon dont il pourrait ressembler à l'<--
opérateur.Réponses:
C'est ce qu'on appelle l' opérateur de comparaison à trois .
Selon la proposition de papier P0515 :
La référence cpp dit:
la source
<0
", "compare>0
" et "compare==0
", ils signifient les<=>
retours une valeur négative, positive ou nulle, selon les arguments. Tout commestrncmp
etmemcmp
.'a' < 'a'
et'c' < 'a'
sont à la fois faux,'a' < 'a'
et'a' < 'c'
ne sont pas. EN ordre fort, ce qui suit est vrai:a != b
→a < b || b < a
operator==(T x, T y) { return !(x < y) && !(y < x); }
etoperator!=(T x, T y) { return (x < y) || (y < x); }
- ah-ha! Bien sûr, cela est moins efficace qu'un vrai==
car il invoque la comparaison deux fois, mais toujours soigné.< 0
à true. Autrement dit, sia < b
alors(a <=> b) < 0
est toujours vrai.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:
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: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 5std::
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.bool
types, intégral et pointeur,<=>
renvoiestrong_ordering
.<=>
, et il existe des hétérogènes intégrésoperator<=>(T*, nullptr_t)
. Seules les comparaisons de pointeurs vers 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 à virgule flottante plus grand.<=>
renvoie la même chose que le type sous-jacent de l'énumération<=>
.nullptr_t
,<=>
retournestrong_ordering
et rapporte toujoursequal
.T[N] <=> T[N]
renvoie le même type queT
's<=>
et effectue une comparaison lexicographique élément par élément. Il n'y en a pas<=>
pour les autres tableaux.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.
la source
_equality
types sont morts: il s'est avéré que cela fonctionne<=>
bien avec les quatre opérateurs relationnels mais pas aussi bien avec les deux opérateurs d'égalité (bien qu'il y ait du sucre syntaxique intense pour soutenir le cas commun où vous voulez tous).Cette réponse est devenue sans objet depuis que la page Web référencée a changé
La page Web à laquelle vous faites référence a été endommagée. Il était beaucoup édité ce jour-là et les différentes parties n'étaient pas synchronisées. Le statut quand je le regardais était:
En haut de la page, il répertorie les opérateurs de comparaison existants (en C ++ 14). Il n'y en a pas
<=>
.Au bas de la page, ils auraient dû lister les mêmes opérateurs, mais ils se sont trompés et ont ajouté cette future suggestion.
gcc
ne sait pas<=>
encore (et avec-std=c++14
, ne le sera jamais), donc il pense que vous vouliez direa <= > b
. C'est ce qui 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.
la source
<=>
opérateur avec le label (depuis C ++ 20), vous indiquant dans quelle version de la norme l'attendre. L'étiquetage des normes est une convention que cppreference.com suit. Bien sûr, vous n'avez pas de compilateur qui est revenu dans une machine à remonter le temps pour le prendre en charge, mais cpprefernce vous dit (correctement) à quoi vous attendre.