blog.michalt.pl

Spaceship operator w C++ 20

06.10.2019 21:51 - Tech

Czas na kolejny wpis o C++20 i na kolejną nowość. Tym razem padło na spaceship operator, zwany czasem three-way operatorem, który w tym wypadku zaimplementowany został trochę inaczej niż w wielu alternatywnych językach i wygląda dość dziwnie, czyli tak: <=>.
Do zabawy wykorzystałem Microsoft Visual Studio 2019 preview. Clang i GCC nadal bez wsparcia nawet na snapshotach. Mimo to nadal obserwuję rozwój wydarzeń i mam nadzieję, że źródła na następny wpis skompiluję w GCC lub Clangu.

Teoria tegoż operatora dla programistów C znających funkcje porównań nie powinna być nowością, ale pod warunkiem, że nie będziemy mówić o języku C++. Dla przykładu, w Ruby, Perl czy PHP rozwiązanie to zostało zaimplementowane zupełnie inaczej. Nasz operator to tak naprawdę 3 w 1. W teorii odpowiada on nam na pytanie, czy wartość po lewej jest większa, mniejsza czy równa od tej po prawej. We wcześniej wspomnianych językach zwraca on -1 dla wartości mniejszej po lewej, 1 dla większej i 0 dla równej.


W C++ jest inaczej, tu mamy 4 w 1. Operator zwraca nam specyficzny dla porównywanych typów obiekt: strong_ordering, weak_ordering i partial_ordering.

strong_ordering – tu musimy mieć do czynienia z danymi, których nie da się wyodrębnić (nie posiadają składowych, jak klasy i struktury lub części dziesiętnej, jak typy zmniennoprzecinkowe), np. int <=> int.
Dane te dla któregoś spośród operatorów: <,== ,> muszą zwracać wartość true.

partial_ordering – tu mamy do czynienia z danymi, które można wyodrębniać, czyli np. z klasami lub strukturami, które zawierają kilka publicznych atrybutów. Dane dla każdego z operatorów <,== ,> mogą zwracać false.

weak_ordering – tu mamy do czynienia z danymi, które również można wyodrębnić, ale muszą one dla któregoś z operatorów <,== ,> zwracać wartość true.

Co ciekawe, spaceship operator dla typów float i double zwraca obiekt typu partial_ordering. Dane int, char, bool oraz wskaźniki każdego typu zawsze zwracają obiekt strong_ordering.


Sprawdzenie wartości zwracanej przez spaceship operator odbywa się dosyć pokrętnie, ponieważ musimy ją przyrównać do zera.

kod spaceship operator

Jeśli wartość jest mniejsza od zera, lewy argument jest mniejszy. Jeśli większa, lewy jest mniejszy. Jeśli równe zero, oba argumenty mają tę samą wartość.

uruchomiony kod spaceship operatora

Jeśli lubicie tradycyjne rozwiązania, zawsze możecie zaimplementować własny wariat, który zadziała tak jak w językach wyższego poziomu:

przeciążony operator spaceship


wynik działania przeciążonego operatora spaceship


Aby móc pobawić się nowościami na Visual Studio, należy pamiętać, aby ustawić standard języka na /std:c++latest.
To wszystko w tym wpisie. Miłego kodzenia :)