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:
"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.
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<=>
.
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 _ .
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
}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.
bool
, types intégral et pointeur, <=>
returnsstrong_ordering
.<=>
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.<=>
renvoie la même chose que le type<=>
du type sous-jacent de l'énumération.nullptr_t
, <=>
renvoiestrong_ordering
et donne 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 a pas<=>
pour d'autres tableaux.void
il 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.
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'expressiona <=> b
renvoie un objet qui compare<0
sia < b
, compare>0
sia > b
et compare==0
sia
. etb
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
impliquef(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
silhs < rhs
- compare
>0
silhs > rhs
- et compare
==0
silhs
etrhs
sont égaux/équivalents.
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.