1. C++ / Говнокод #27397

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 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 хуиты для частных случаев.

    Запостил: j123123, 07 Мая 2021

    Комментарии (9) RSS

    • Как в Perl:)

      То есть теперь не нужно вручную объяснять компилятору, что если A > B, то B < A, а можно сделать одну фцнкйию, которая вернет -1, 0 и 1? Типа "меньше", "равно", "больше"?
      Ответить
      • > То есть теперь не нужно вручную объяснять компилятору, что если A > B, то B < A, а можно сделать одну фцнкйию, которая вернет -1, 0 и 1? Типа "меньше", "равно", "больше"?

        Нет, не совсем так. Это крестоговно, тут всё сложнее.
        Ответить
        • https://habr.com/ru/company/yandex_praktikum/blog/555704/#comment_23001838
          > Это не совсем так, причина там в другом. Оператор <=> вообще никогда не генерирует операторы == и != сам по себе, он генерирует только <, >, <= и >=, при этом неважно, какой ордеринг применяется. Просто есть соглашение, что дефолтные операторы == и != генерируются как бы «в довесок», если оператор <=> определен как defaulted, а так операторы «сравнения» и «равенства» как бы логически разделены и независимы. Идея была в том, что к результату выполнения operator<=>() предъявляются определенные требования, которые могут быть игнорированы при сравнении «на равенство», скажем, векторов или строк. Можно определить, что один вектор не равен другому, просто сравнив длину, и если длины разные, то сразу остановиться. Поэтому было решено, что не следует пользоваться кастомной реализацией operator<=>() для создания дефолтной реализации операторов сравнения на строгое равенство. В случае кастомной реализации operator<=>() по-прежнему можно при желании явным образом определить operator==() как default и получить его (и != соответственно). Вот здесь подробнее написано:

          http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1185r2.html
          Ответить
        • Скажем, если взять какие-нибудь плавучиепитуховые числа, и сравнивать их, то если "false == (NaN == NaN)" и "false == (NaN < NaN)" то это еще не значит, что "true == (NaN > NaN)". Охуенно, не правда ли?
          Ответить
    • > Пример

      > В структуру X я добавил всего одну строчку, определяющую операцию <=>. Заметьте, что я даже не написал, что именно она делает:

      #include <iostream>
      
      struct X {
          auto operator<=>(const X&) const = default; // <-- !
          int a;
      };


      > И C++ всё сделал за меня. Это сработает и в более сложных случаях, например, когда у X несколько полей и базовых классов. При этом всё, что есть в X, должно поддерживать сравнение.

      Да, охуеть конечно, ничего не скажешь. А под что-то кроме сравнения ее можно использовать? Почему надо под какую-то мелкую частную поебень со сравнением через "<" "==" ">" пилить какую-то частную хуйню?
      Ответить
      • Стесняюсь спросить: а если я определю оператор <=> и оператор <=, то что будет?
        Ответить
        • Лучше об этом не думать...
          Ответить
        • ЕМНИП <=> используется если явно не определён соответствующий оператор.

          Но это не точно, потому что я это не использую. Самое ненужное добавление ИМХО. Лучше бы рефлексию запилили.
          Ответить
          • > Самое ненужное

            Сам оператор нинужен, конечно. А вот = default для операторов сравнения выглядит вполне няшно, наконец-то не надо будет генерить эту фигню макросами и перечислять поля для сравнения вручную.
            Ответить

    Добавить комментарий