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_orderingz wartościami { less, equal, greater} niejawnie konwertuje do:
weak_orderingo wartościach { less, equivalent, greater}
partial_orderingo wartościach { less, equivalent, greater}
strong_equalityo wartościach { unequal, equal, unequal}
weak_equalityo wartościach { nonequivalent, equivalent, nonequivalent}
weak_orderingz wartościami { less, equivalent, greater} niejawnie konwertuje do:
partial_orderingo wartościach { less, equivalent, greater}
weak_equalityo wartościach { nonequivalent, equivalent, nonequivalent}
partial_orderingz wartościami { less, equivalent, greater, unordered} niejawnie konwertuje do:
weak_equalityo wartościach { nonequivalent, equivalent, nonequivalent, nonequivalent}
strong_equalityz wartościami { equal, unequal} domyślnie konwertuje się na:
weak_equalityz 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, 0ale 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_orderingi 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_orderingi 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
voidnie 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.