namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:compare

<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 und
  • a == 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;
    std::weak_ordering operator<=>(const rational& b) const { return d * b.n <=> n * b.d; }
    std::weak_ordering operator== (const rational& b) const { return d * b.n ==  n * b.d; }
    std::weak_ordering operator<=>(int number) const { return d <=> n * number; }
    std::weak_ordering 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 erachtet werden, z.B. Zeichenketten, für die Groß- und Kleinschreibung ignoriert werden kann, oder ungekürzte Brüche.
  • std::partial_ordering erlaubt als Vergleichsergebnis unordered.

Der vom Compiler erzeugte Vergleich liefert das lexigraphische 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.

kennen/include/compare.txt · Zuletzt geändert: 2020-06-23 09:59 von rrichter