Während ich versuche , darüber zu erfahren , C ++ Operatoren, stieß ich auf einem seltsamen Vergleichsoperator auf cppreference.com , * in einer Tabelle , die wie folgt aussah:
"Nun, wenn dies in C ++ übliche Operatoren sind, lerne ich sie besser", dachte ich. Aber alle meine Versuche, dieses Rätsel zu lösen, waren erfolglos. Selbst hier bei Stack Overflow hatte ich kein Glück bei meiner Suche.
Gibt es eine Verbindung zwischen <=> und C ++ ?
Und wenn ja, was macht dieser Operator genau?
* In der Zwischenzeit hat cppreference.com diese Seite aktualisiert und enthält nun Informationen zum <=>
Betreiber.
bar< foo::operator<=>
ist ein Beispiel dafür, wie es wie der<--
Operator sein könnte.Antworten:
Dies wird als Drei-Wege-Vergleichsoperator bezeichnet .
Gemäß dem Papiervorschlag P0515 :
Die Referenz sagt:
quelle
<0
", "Vergleichen>0
" und "Vergleichen==0
" bedeutet, bedeutet dies, dass die<=>
Rückgabe je nach Argument einen negativen, positiven oder Nullwert ergibt. Ähnlich wiestrncmp
undmemcmp
.'a' < 'a'
und'c' < 'a'
beide falsch sind'a' < 'a'
und'a' < 'c'
nicht. In starker Reihenfolge ist folgendes wahr:a != b
→a < b || b < a
operator==(T x, T y) { return !(x < y) && !(y < x); }
undoperator!=(T x, T y) { return (x < y) || (y < x); }
- ah-ha! Dies ist natürlich weniger effizient als ein True,==
da es den Vergleich zweimal aufruft, aber immer noch ordentlich.< 0
zu true ausgewertet wird. Das heißt, wenna < b
dann(a <=> b) < 0
immer wahr ist.Am 11.11.2017 nahm das ISO C ++ - Komitee den Vorschlag von Herb Sutter für den Dreiwege-Vergleichsoperator <=> "Raumschiff" als eine der neuen Funktionen an, die C ++ 20 hinzugefügt wurden . In dem Artikel mit dem Titel Konsistenter Vergleich Sutter demonstrieren Maurer und Brown die Konzepte des neuen Designs. Für einen Überblick über den Vorschlag hier ein Auszug aus dem Artikel:
Vergleichskategorien
Fünf Vergleichskategorien werden als
std::
Typen definiert , die jeweils die folgenden vordefinierten Werte aufweisen:Implizite Konvertierungen zwischen diesen Typen sind wie folgt definiert:
strong_ordering
mit Werten {less
,equal
,greater
} konvertiert implizit auf:weak_ordering
mit Werten {less
,equivalent
,greater
}partial_ordering
mit Werten {less
,equivalent
,greater
}strong_equality
mit Werten {unequal
,equal
,unequal
}weak_equality
mit Werten {nonequivalent
,equivalent
,nonequivalent
}weak_ordering
mit Werten {less
,equivalent
,greater
} konvertiert implizit auf:partial_ordering
mit Werten {less
,equivalent
,greater
}weak_equality
mit Werten {nonequivalent
,equivalent
,nonequivalent
}partial_ordering
mit Werten {less
,equivalent
,greater
,unordered
} konvertiert implizit auf:weak_equality
mit Werten {nonequivalent
,equivalent
,nonequivalent
,nonequivalent
}strong_equality
mit Werten {equal
,unequal
} wird implizit konvertiert in:weak_equality
mit Werten {equivalent
,nonequivalent
}Drei-Wege-Vergleich
Das
<=>
Token wird eingeführt. Die Zeichenfolge wird im alten Quellcode mit einem<=>
Token versehen<= >
. Muss beispielsweiseX<&Y::operator<=>
ein Leerzeichen hinzufügen, um seine Bedeutung beizubehalten.Der überladbare Operator
<=>
ist eine Drei-Wege-Vergleichsfunktion und hat Vorrang höher als<
und niedriger als<<
. Es gibt einen Typ zurück, der mit Literal verglichen werden kann,0
aber andere Rückgabetypen sind zulässig, z. B. zur Unterstützung von Ausdrucksvorlagen. Alle<=>
in der Sprache und in der Standardbibliothek definierten Operatoren geben einen der 5 oben genanntenstd::
Vergleichskategorietypen zurück.Für Sprachtypen werden die folgenden integrierten
<=>
Vergleiche desselben Typs bereitgestellt. Alle sind constexpr , sofern nicht anders angegeben. Diese Vergleiche können nicht heterogen mit skalaren Promotions / Conversions aufgerufen werden.bool
Integral- und Zeigertypen wird<=>
zurückgegebenstrong_ordering
.<=>
, und es sind integrierte heterogene Funktionen vorhandenoperator<=>(T*, nullptr_t)
. Nur Vergleiche von Zeigern auf dasselbe Objekt / dieselbe Zuordnung sind konstante Ausdrücke.<=>
zurückpartial_ordering
und kann heterogen aufgerufen werden, indem Argumente auf einen größeren Gleitkommatyp erweitert werden.<=>
dasselbe zurück wie die zugrunde liegenden Typen der Aufzählung<=>
.nullptr_t
,<=>
kehrtstrong_ordering
und immer Ausbeutenequal
.T[N] <=> T[N]
den gleichen Typ wieT
's zurück<=>
und führt einen lexikografischen elementweisen Vergleich durch. Es gibt keine<=>
für andere Arrays.void
es gibt keine<=>
.Zum besseren Verständnis der Funktionsweise von diesem Betreiber zu verstehen, benutzen Sie bitte das Original lesen Papier . Dies ist genau das, was ich mithilfe von Suchmaschinen herausgefunden habe.
quelle
_equality
Typen gestorben sind: Es stellte sich heraus, dass dies<=>
mit den vier relationalen Operatoren gut funktioniert, aber nicht so gut mit den beiden Gleichheitsoperatoren (obwohl es einen intensiven syntaktischen Zucker gibt, der den allgemeinen Fall unterstützt, in dem Sie alle wollen).Diese Antwort ist irrelevant geworden, da sich die referenzierte Webseite geändert hat
Die Webseite, auf die Sie verweisen, war fehlerhaft. Es wurde an diesem Tag viel bearbeitet und verschiedene Teile waren nicht synchron. Der Status, als ich es betrachtete, war:
Oben auf der Seite werden die aktuell vorhandenen Vergleichsoperatoren (in C ++ 14) aufgelistet. Da ist kein
<=>
da.Am Ende der Seite hätten sie dieselben Operatoren auflisten sollen, aber sie haben diesen zukünftigen Vorschlag vermasselt und hinzugefügt.
gcc
weiß noch nichts darüber<=>
(und mit-std=c++14
, wird es nie tun), also denkt es, dass du es gemeint hasta <= > b
. Dies erklärt die Fehlermeldung.Wenn Sie in fünf Jahren dasselbe versuchen, erhalten Sie wahrscheinlich eine bessere Fehlermeldung, etwa
<=> not part of C++14.
quelle
<=>
Operator mit dem Label (seit C ++ 20) und gibt an, in welcher Version des Standards es zu erwarten ist. Die Standardkennzeichnung ist eine Konvention, der cppreference.com folgt. Natürlich haben Sie keinen Compiler, der in einer Zeitmaschine zurückgekommen ist, um ihn für Sie zu unterstützen, aber cpprefernce sagt Ihnen (richtig), was Sie erwartet.