namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


kennen:include:compare
no way to compare when less than two revisions

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


kennen:include:compare [2020-07-25 09:37] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== <compare> ======
 +===== Dreiwegevergleich =====
 +
 +Binde diesen Header ein, um den Dreiwegevergleich ("spaceship" operator ''%%<=>%%'') für eigene Typen zu definieren.
 +[[kennen:operator#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
 +
 +<code cpp 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)
 +    );
 +}
 +</code>
 +oder selbst definiert werden. Dann wird der Gleichheitsoperator nicht automatisch mit generiert:
 +<code cpp 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 );
 +}
 +</code>
 +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 Vergleichsergebnis ''unordered'': für NaNs von Gleitkommazahlen sind ''a<b'', ''a==b'' und ''a>b'' zugleich ''false''.
 +    
 +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 [[kennen:stl#Funktionsadapter]] wie ''less<>'', ''greater<>'' usw.
 +
 +
 +
  
kennen/include/compare.txt · Zuletzt geändert: 2020-07-25 09:37 von 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki