- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
// https://habr.com/ru/company/yandex_praktikum/blog/555704/
// Стандарт C++20: обзор новых возможностей C++. Часть 2 «Операция ''Космический Корабль''»
// Предположим, вы определили структуру, содержащую одно число:
struct X {
int a;
};
// Мы хотим сделать так, чтобы значения этой структуры можно было сравнивать друг с другом.
// Для этого придётся написать шесть операций:
bool operator== (X l, X r) { return l.a == r.a; }
bool operator!= (X l, X r) { return l.a != r.a; }
bool operator>= (X l, X r) { return l.a >= r.a; }
bool operator<= (X l, X r) { return l.a <= r.a; }
bool operator< (X l, X r) { return l.a < r.a; }
bool operator> (X l, X r) { return l.a > r.a; }
// А теперь представьте, что мы хотим сравнивать элементы этой структуры не только между собой,
// но также с числами int. Количество операций возрастает с шести до 18:
bool operator== (X l, int r) { return l.a == r; }
bool operator!= (X l, int r) { return l.a != r; }
bool operator>= (X l, int r) { return l.a >= r; }
bool operator<= (X l, int r) { return l.a <= r; }
bool operator< (X l, int r) { return l.a < r; }
bool operator> (X l, int r) { return l.a > r; }
bool operator== (int l, X r) { return l == r.a; }
bool operator!= (int l, X r) { return l != r.a; }
bool operator>= (int l, X r) { return l >= r.a; }
bool operator<= (int l, X r) { return l <= r.a; }
bool operator< (int l, X r) { return l < r.a; }
bool operator> (int l, X r) { return l > r.a; }
// Что делать? Можно позвать штурмовиков. Их много, и они быстро напишут 18 операций.
// Или воспользоваться «космическим кораблём». Эту новую операцию в C++ называют
// «космический корабль», потому что она на него похожа: <=>. Более формальное название
// «трёхстороннее сравнение» фигурирует в документах Стандарта.
А можно добавить гомоиконность, которой можно наметушить не только какой-то там космический корабль (ради которого в крестокомпиляторах надо синтаксический анализатор менять, чтоб добавить новое синтаксиальное говно для этого <=>), а хоть целую, блядь, эскадрилью космических кораблей, которая работает не только для "больше меньше равно", но и для любой вообразимой поебени
Но крестушкам конечно привычней добавить какой-то ad-hoc хуиты для частных случаев.
MAKAKA 07.05.2021 16:16 # 0
То есть теперь не нужно вручную объяснять компилятору, что если A > B, то B < A, а можно сделать одну фцнкйию, которая вернет -1, 0 и 1? Типа "меньше", "равно", "больше"?
j123123 07.05.2021 16:23 # 0
Нет, не совсем так. Это крестоговно, тут всё сложнее.
j123123 07.05.2021 16:25 # 0
> Это не совсем так, причина там в другом. Оператор <=> вообще никогда не генерирует операторы == и != сам по себе, он генерирует только <, >, <= и >=, при этом неважно, какой ордеринг применяется. Просто есть соглашение, что дефолтные операторы == и != генерируются как бы «в довесок», если оператор <=> определен как defaulted, а так операторы «сравнения» и «равенства» как бы логически разделены и независимы. Идея была в том, что к результату выполнения operator<=>() предъявляются определенные требования, которые могут быть игнорированы при сравнении «на равенство», скажем, векторов или строк. Можно определить, что один вектор не равен другому, просто сравнив длину, и если длины разные, то сразу остановиться. Поэтому было решено, что не следует пользоваться кастомной реализацией operator<=>() для создания дефолтной реализации операторов сравнения на строгое равенство. В случае кастомной реализации operator<=>() по-прежнему можно при желании явным образом определить operator==() как default и получить его (и != соответственно). Вот здесь подробнее написано:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1185r2.html
j123123 07.05.2021 16:30 # 0
j123123 07.05.2021 16:16 # 0
> В структуру X я добавил всего одну строчку, определяющую операцию <=>. Заметьте, что я даже не написал, что именно она делает:
> И C++ всё сделал за меня. Это сработает и в более сложных случаях, например, когда у X несколько полей и базовых классов. При этом всё, что есть в X, должно поддерживать сравнение.
Да, охуеть конечно, ничего не скажешь. А под что-то кроме сравнения ее можно использовать? Почему надо под какую-то мелкую частную поебень со сравнением через "<" "==" ">" пилить какую-то частную хуйню?
MAKAKA 07.05.2021 16:19 # 0
bormand 07.05.2021 16:26 # 0
Soul_re@ver 07.05.2021 16:32 # 0
Но это не точно, потому что я это не использую. Самое ненужное добавление ИМХО. Лучше бы рефлексию запилили.
bormand 07.05.2021 16:33 # 0
Сам оператор нинужен, конечно. А вот = default для операторов сравнения выглядит вполне няшно, наконец-то не надо будет генерить эту фигню макросами и перечислять поля для сравнения вручную.