W dniu 11.11.2017 r. Komitet ISO C ++ przyjął propozycję Herb Suttera dotyczącą trójstronnego operatora porównania <=> „statku kosmicznego” jako jedną z nowych funkcji dodanych do C ++ 20 . W artykule zatytułowanym Spójne porównanie Sutter, Maurer i Brown demonstrują koncepcje nowego projektu. Aby zapoznać się z wnioskiem, oto fragment tego artykułu:
Wyrażenie a <=> b zwraca obiekt, który porównuje <0 jeśli a <b , porównuje > 0 jeśli a> b , i porównuje == 0, jeśli aib są równe / równoważne.
Typowy przypadek: pisanie wszystkich porównań dla twojego typu X z typem YTypowy , z semantyką składową, po prostu napisz:
auto X::operator<=>(const Y&) =default;
Przypadki zaawansowane: aby napisać wszystkie porównania dla twojego typu X z typem Y , po prostu napisz operator <=>, który przyjmuje Y , może użyć
= default, aby uzyskać semantykę członkowską w razie potrzeby, i zwraca odpowiedni typ kategorii:
- Zwróć _ordering, jeśli Twój typ naturalnie obsługuje < , a my efektywnie wygenerujemy symetryczne < , > , <= , > = , == i
! = ; w przeciwnym razie zwróci _ _equality , a my efektywnie wygenerujemy symetryczny == i ! = .
- Zwróć wartość strong_, jeśli dla twojego typu a == b oznacza f (a) == f (b) (substytucyjność, gdzie f odczytuje tylko stan istotny dla porównania, który jest dostępny przy użyciu publicznych elementów stałych ), w przeciwnym razie zwraca wartość
słabe_ .
Kategorie porównawcze
Pięć kategorii porównawczych jest zdefiniowanych jako std::
typy, z których każda ma następujące predefiniowane wartości:
+--------------------------------------------------------------------+
| | 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 | |
+------------------+------+------------+---------------+-------------+
Niejawne konwersje między tymi typami są zdefiniowane w następujący sposób:
strong_ordering
z wartościami { less
, equal
, greater
} niejawnie konwertuje do:
weak_ordering
o wartościach { less
, equivalent
, greater
}
partial_ordering
o wartościach { less
, equivalent
, greater
}
strong_equality
o wartościach { unequal
, equal
, unequal
}
weak_equality
o wartościach { nonequivalent
, equivalent
, nonequivalent
}
weak_ordering
z wartościami { less
, equivalent
, greater
} niejawnie konwertuje do:
partial_ordering
o wartościach { less
, equivalent
, greater
}
weak_equality
o wartościach { nonequivalent
, equivalent
, nonequivalent
}
partial_ordering
z wartościami { less
, equivalent
, greater
, unordered
} niejawnie konwertuje do:
weak_equality
o wartościach { nonequivalent
, equivalent
, nonequivalent
, nonequivalent
}
strong_equality
z wartościami { equal
, unequal
} domyślnie konwertuje się na:
weak_equality
z wartościami { equivalent
, nonequivalent
}
Porównanie trójstronne
<=>
Token wprowadzony. Sekwencja znaków <=>
symbolizuje <= >
w starym kodzie źródłowym. Na przykład X<&Y::operator<=>
musi dodać spację, aby zachować swoje znaczenie.
Przeciążalny operator <=>
jest trójstronną funkcją porównania i ma pierwszeństwo wyższe niż <
i niższe niż <<
. Zwraca typ, który można porównać z literałem, 0
ale dozwolone są inne typy zwracania, takie jak obsługa szablonów wyrażeń. Wszystko<=>
operatory zdefiniowane w języku i standardowej bibliotece zwracają jeden z 5 wyżej wymienionych std::
typów kategorii porównawczych.
W przypadku typów języków dostępne są następujące wbudowane <=>
porównania tego samego typu. Wszystkie są constexpr , chyba że zaznaczono inaczej. Tych porównań nie można wywoływać heterogenicznie przy użyciu skalarnych promocji / konwersji.
- Dla
bool
, integralny i typy wskaźnik, <=>
zwrotówstrong_ordering
.
- W przypadku typów wskaźników różne kwalifikacje cv i konwersje pochodne do bazy mogą wywoływać jednorodne wbudowane
<=>
, a wbudowane są heterogeniczne operator<=>(T*, nullptr_t)
. Jedynie porównania wskaźników do tego samego obiektu / alokacji są wyrażeniami stałymi.
- W przypadku podstawowych typów zmiennoprzecinkowych
<=>
zwraca partial_ordering
i można je heterogenicznie wywoływać, rozszerzając argumenty na większy typ zmiennoprzecinkowy.
- W przypadku wyliczeń
<=>
zwraca to samo, co typ bazowy wyliczenia <=>
.
- Dla
nullptr_t
, <=>
zwrotów strong_ordering
i zawsze plonów equal
.
- W przypadku tablic możliwych do skopiowania
T[N] <=> T[N]
zwraca ten sam typ, co T
„s” <=>
i dokonuje porównania leksykograficznego z zastosowaniem elementów. Nie ma <=>
innych tablic.
- Bo
void
nie ma <=>
.
Aby lepiej zrozumieć wewnętrzne funkcjonowanie tego operatora, należy zapoznać się z oryginalną papier . Właśnie tego się dowiedziałem za pomocą wyszukiwarek.