Inhaltsverzeichnis
<compare>
Dreiwegevergleich
Binde diesen Header ein, um den Dreiwegevergleich ("spaceship" operator <=>
) für eigene Typen zu definieren.
Vergleiche auf Ordnungsrelationen und (Un-)Gleichheit, evtl. auch zum Vergleich mit anderen Typen, werden ab C++20 zusammengefasst:
a < b
wird zu(a <=> b) < 0
,a > b
entspricht(a <=> b) > 0
unda == b
ist äquivalent zu(a <=> b) == 0
.
Alle Vergleichsoperatoren werden damit nutzbar. Der Operator kann vom Compiler generiert
- spaceship_default.cpp
#include <compare> #include <cassert> struct Foo { int x, y; auto operator<=>(const Foo&) const = default; }; int main() { Foo a{1,3}, b{2,1}; assert( (a < b) && (a <= b) && !(a == b) && (a != b) && !(a >= b) && !(a > b) ); }
oder selbst definiert werden. Dann wird der Gleichheitsoperator nicht automatisch mit generiert:
- spaceship_own.cpp
#include <compare> #include <cassert> struct rational { int d = 0, n = 1; auto operator<=>(const rational& b) const { return d * b.n <=> n * b.d; } bool operator== (const rational& b) const { return d * b.n == n * b.d; } auto operator<=>(int number) const { return d <=> n * number; } bool operator== (int number) const { return d == n * number; } }; int main() { rational a, b{1, 2}; assert( a != b && 1 > b ); }
Auch Vergleiche mit anderen Typen können überladen werden.
Unterscheiden sich die Typen der Operanden, sind sowohl x <=> y
und y <=> x
nutzbar:
Aus 1 > b
würde (1 <=> b) > 0
.
Da aber kein operator<=>(int, rational)
definiert ist, schreibt der Compiler dies zu 0 > (b <=> 1)
um.
Kategorien
Der Header <compare>
definiert mehrere mögliche Ergebnistypen für den Dreiwegevergleich:
std::strong_ordering
vergleicht alle Elemente einer Struktur/Klasse,std::weak_ordering
erlaubt unterscheidbare Objekte, die als gleich, aber nicht ersetzbar erachtet werden, z.B. Zeichenketten, für die Groß- und Kleinschreibung ignoriert werden kann,std::partial_ordering
erlaubt als Vergleichsergebnisunordered
: für NaNs von Gleitkommazahlen sinda<b
,a==b
unda>b
zugleichfalse
.
Der vom Compiler erzeugte Vergleich liefert das lexikographische Ergebnis der Komponenten in der Reihenfolge ihrer Definition. Als Rückgabetyp kommt die stärkste gemeinsame Vergleichskategorie zum Einsatz.
Funktionsadapter
Die Struktur compare_three_way
besitzt einen Funktionsoperator operator()(T&& t, U&& u)
, der für Objekte beliebiger Typen den Spaceship-Vergleich t <=> u
aufrufen kann, sofern dieser definiert ist.
Vergleiche dazu Funktionsadapter wie less<>
, greater<>
usw.