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

    +17

    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
    #include <iostream>
     
    template< class Val >struct SwithClass
    {
        SwithClass( const Val & v ):val(v){}
        void operator() (){}
        template < class E, class F, class ... Args > void operator() ( E e, F f, Args ... args )
        {
           if( e==val )  f(); 
           else  (*this)( args... );
        }
    private:
        Val val;
    };
     
    template< class Val > SwithClass<Val> Swith( const Val& v ){  return SwithClass<Val>(v);}
     
    int main()
    {
        int x = 8;
        Swith( x )
        (
           1,  [](){  std::cout <<"x=1" << std::endl;  },
           8,  [](){  std::cout <<"x=8" << std::endl;  } 
        );
       return 0;
    }

    http://ideone.com/Xbj46U

    Запостил: LispGovno, 11 Ноября 2012

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

    • Забыл пояснить: это оттуда.
      Ответить
    • Фу, O(n).
      Ответить
      • Ещё скажи, что случайную сортировку не любишь.
        Ответить
        • Случайную сортировку я люблю, ведь у нее божественное O(n!) а не O(n).
          Ответить
          • Неа. Случайная же может никогда не закончиться, если повезёт.
            Ответить
            • Может, но вроде матожидание количества попыток будет n!
              Ответить
              • O-большое, это разве среднее значение?
                Ответить
                • Да, в термине "среднее время O(f(n))" O - среднее значение (Капитан Тавтология)
                  Ответить
                • О- это сложность, выраженная в порядке кол-ва операций. Принято указывать, какая именно сложность имеется в виду: худший случай или амортизированная ("среднее значение").
                  Для сортировок часто в качестве операций выбирают требуемое число сравнений, именно, его и привёл борманд (правда, в вики n! * (n-1)).
                  Ответить
              • n·n!
                Ответить
                • Хм, а откуда еще одно n?
                  Ответить
                  • А, понял, надо же проверять упорядоченность. Вот она на каждой попытке и наматывает n-1 сравнение.
                    Ответить
                    • Кстати, а нет ли алгоритмов с большей сложностью, при этом корректных, без глупых ненужных операций?
                      Ответить
        • sleep sort вне конкуренции
          Ответить
    • oh godh, why sho sweeth?
      Ответить
    • Как модифицировать, чтобы добавить Default?
      Ответить
      • добавить класс Guru::Defaulth, который будет иметь метод operator == с любым аргументом и возвращать thrue
        при желании, можно сделать хелпер is_defaulth<T>, который для Defaulth перегрузкой будет иметь enum { valueh = trueh; }, а для всех остальных - falseh, и от него плясать (первую часть не отменяет, зато можно извратиться и дефолтх отложить на последнюю очередь, заодно проверить, чтобы их было не больше одного)
        Ответить
      • Реализовал идею Дефекейта: http://ideone.com/TPdkUJ.
        Ответить
        • > Дефекейта

          Дефейкейстры
          Ответить
        • Не бро, плохо релизовал:
          http://ideone.com/j1sxa2
          Ответить
          • > Не бро, плохо релизовал
            Согласен. Пофиксил.

            http://ideone.com/4ROpgg

            Причем то, что defaulht стоит последним проверяется на этапе компиляции: http://ideone.com/G9FfN0
            Ответить
            • А за счет чего проверяется это на этапе компиляции? Как я понял должна была выбраться Defaulht перегрузка функции и молча скомпилироваться, если в середине списка параметров Defaulht встретится.

              PS: Ошибка не говорящая совершенно. static_assert бы туда...
              Ответить
              • > А за счет чего проверяется это на этапе компиляции?
                За счет несравнимости Defaulht с другими типами.
                Ответить
                • Ну вроде как как только первый Defaulht встретится, так и все пойдет в ветку перегрузки Defaulht , а там вроде никакой сравнимости нет и проблем быть не должно... Хотя понял, почему... args нет в Defaulht ветке.
                  Ответить
              • static_assert
                в целом он какой-то broken этот static_assert, я не смог его заставить заработать на моем пыщь пыщь говнокоде
                при этом я уронил liveworkspace.org, и теперь проверить поведение на BOOST_STATIC_ASSERT пока негде
                Ответить
                • а нет, это broken разворачивание args..., когда их уже нет
                  в общем вот такой вот говнокот:
                  http://ideone.com/bpRJVI
                  если поставить defau1t последним, то г++ инстанциируя do_case<true>(f, args...) сделает непотребность в виде do_case<true>(f, defau1t, f, {}), и конечно стасик_ассерт заругает

                  что с этим делать?

                  еще интересней: http://ideone.com/N0ZuP5
                  sorry, unimplemented
                  Ответить
                • Хаха, хакер. Уронил liveworkspace.org
                  Ответить
                  • Реально. До сих пор сервер не поднимается...
                    Ответить
              • Вот вариант со static_assert
                http://ideone.com/e7vZTr
                Ответить
                • сюрприз, но в с/с++ default: в свиче может стоять где угодно, хоть первым, и это не влияет на его жизнеспособность
                  Ответить
                  • На крестофоруме говорят, что разыменование указателя - уб. Но я считаю, что код ниже не уб:
                    void * p = &*&p;
                    int * p2=0;
                    int * p1 = &*p2;

                    http://ideone.com/PABJQf
                    Ответить
                    • там разве речь шла не о другом?
                      типа о ((mytype *)0)->foo()
                      Ответить
                      • Ну а в таком случае для виртуальных функций - уб, а для не виртуальных и статических - пох.
                        Ответить
                        • Емнип:
                          int *p = 0;
                          *p; // не UB
                          *p = 2; // креш, не UB
                          Class *c = 0;
                          *c; // не UB
                          *c.x(); // UB

                          P.S. Сейчас пороемся в стандартах.
                          Ответить
                          • >*p = 2; // креш, не UB
                            В стандарте нет понятия креш. На некоторых платформах и средах будут испорчены вектора прерываний или ещё что-нибудь. Это есть UB по стадарту.
                            Ответить
                            • Вот и все, что есть в стандарте про оператор *:
                              The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. If the type of the expression is “pointer to T,” the type of the result is “T.”
                              [Note: a pointer to an incomplete type (other than cv void ) can be dereferenced. The lvalue thus obtained can be used in limited ways (to initialize a reference, for example); this lvalue must not be converted to an rvalue, see 4.1. ]

                              Раз не описано - значит поведение на кривых указателях включая NULL будем считать UB.
                              Ответить
                          • >*c; // не UB
                            Вот и я думаю, что это не уб. уб начнется, когда с значением расположеным по этому указателю что-то начнешь делать, то есть &*c - не уб
                            Ответить
                          • в общем разыменование нулевого указателя в с++11 не UB
                            они даже п.1.9 про UB переписали
                            http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232
                            Ответить
                            • Ясно, все таки пофиксили стандарт.
                              Ответить
                            • короче foo->bar() не УБ, если foo указывает хз куда, а bar() не виртуальное и не трогает его данные?
                              Ответить
                    • > разыменование указателя - уб
                      Как же я теперь буду писать на сишечке... Все мои программы превратились в тыквуUB...

                      P.S. А что в этом коде не так - это ведь тоже самое, что и void *p = &p;
                      Ответить
                      • А нахрен тебе это на сишечке нужно?
                        Ответить
                        • Это в крестах нужно для:
                          std::shared_ptr<int> p=...;
                          std::shared_ptr<int>* p1=&p;
                          int* p2=&*p;
                          //p2 be equal nullptr or not to be?
                          Ответить
                          • Фактически в 3ей сточке разыменовывается как бы возможно 0ой указатель.
                            Ответить
                            • Здесь то да, но все что я писал выше относилось к строке void * p = &*&p, в которой нет никаких NULL'ов, а две строки ниже я заметил намного позже (т.к. их изначально там не было).
                              Ответить
                        • Нахрен я на сишечке пишу int x = *p, тем самым разыменовывая указатель?
                          Ответить
                          • Нахрен тебе разыменовывать указатель, если он нулевой? Если ты хотел упасть, то это не кросплатформенно. На некоторых платформах не упадет.
                            Ответить
                            • > Нахрен тебе разыменовывать указатель, если он нулевой?
                              А где в твоем примере нулевой указатель?

                              UPD: а, так ты код в посте обновил, в p2... ну вот значит в третьей строке UB, а в первой все норм, там никаких нуллов не разыменовывают.
                              Ответить
                  • Если честно - не знал, и никогда не возникало желания его туда поставить...

                    P.S. Разве что это имеет смысл если нужно воспользоваться "проскоком" с одной дефолтовой ветки на ту, которая ниже. http://ideone.com/bNUbad
                    Ответить
                    • >Если честно - не знал, и никогда не возникало желания его туда поставить
                      Ну это же очевидно. Обычная метка.
                      Ответить
                  • Но в нашем случае все условия перебираются последовательно, поэтому лучше поставить default в конец списка.
                    Ответить
                    • В случае сишного свича все условия тоже как-будто тоже перебираются последовательно. По крайней мере все отимизации кресты делают с оглядкой на это, чтобы не нарушить семантику.
                      Ответить
                      • Что значит "как будто перебираются последовательно"? Если метки не пересекаются (а они не пересекаются, иначе ошибка компиляции), то какая разница, в какой порядке перебор?
                        Ответить
                        • В общем, гумно походу не ответит. Я так понял, гумно опять спизднуло, не подумав.
                          Ответить
                          • http://ideone.com/phRtQb
                            Я тебе хотел этот код прислать, но что-то с самого начала пошло не так. ты прав
                            Ответить
                      • А как там семантика свича зависит от порядка сравнений? Одинаковые значения в кейсах он не допускает. Поэтому абсолютно пофиг в каком порядке он их перебирает. Переход будет ровно на одну метку. А как управление будет проскакивать ниже, если забыли поставить break - это уже другой вопрос, ортогональный перебору условий.

                        Я всегда буду обновлять тред перед отправкой.
                        Я всегда буду обновлять тред перед отправкой.
                        Я всегда буду обновлять тред перед отправкой.
                        Ответить
                        • бебебе я первее
                          Ответить
                        • > Я всегда буду обновлять тред перед отправкой.

                          Эта мантра не помогает.
                          Ответить
                        • http://ideone.com/XDkfqp
                          тут default можно ставить где угодно
                          Ответить
                          • http://ideone.com/vEOaby
                            Ответить
                            • Тогда уж стандартный свитч такое тоже не позволяет:
                              http://ideone.com/zz4sUi
                              Ответить
                              • В том и прикол ;) Дефекейт хочет чтобы и тут не позволяло.
                                Ответить
                                • это во время компиляции сравниваемые значения нужно скидывать в контейнер и стасик_ассертом проверять уникальность каждого. В такие моменты понимаешь, что жалко, что в этот момент ты пишешь не на D или Nemerle, где этот было бы как 2 пальца об асфальт.
                                  Ответить
                                  • - А вот в D и Nemerle можно легко запилить свой ООП-switch со статической проверкой
                                    - Но зачем?
                                    Ответить
                                    • Чем тебя Lisp не устраивает? Он позволяет делать свои EDSL, как и D/Nemerle. Для решения некоторых задач это важно.
                                      Ответить
                                      • Я люблю DSL всем сердцем и считаю их основой хорошего API. Просто большая часть приведённых примеров крайне надуманна. И ещё... мне (пока?) не очень нравятся DSL, вводящие синтаксические конструкции, сильно отличающиеся по структуре от языка, на котором они реализованы. Это заставляет пользователей учить новый синтаксис и сильно уменьшает поддержку со стороны IDE.

                                        Например, я очень скептически отношусь к коммон-лисповому макросу loop (да, в нём слишком мало скобок :]), а синтаксис format, как уже замечал недавно @wvxvw, может вынести мозг любому.
                                        Ответить
                                        • Не знаю что там с D. Вроде немного менее радужно. Например класс длинных чисел не работает во время компиляции, что говорит о множестве ограничений. А вот в немерле можно использовать абсолютно всю во время этапа компиляции (всю стандартную библиотеку, не стандартную и даже конструкции языка, что ты накатал в соседней библиотеке).
                                          Ответить
                                  • Вот вариант, который проверяет на уникальность дефолта:

                                    Без дефолта: http://ideone.com/lMAqVQ, http://ideone.com/P9T4HM.

                                    С дефолтом: http://ideone.com/OMftSs, http://ideone.com/9C7pyj.

                                    С двумя дефолтами (статик ассёрт): http://ideone.com/BIdCfc.
                                    Ответить
    • У этой реализации есть свои плюсы:
      http://ideone.com/Kh4Nt9
      Сравнивает строки.
      А можно ввести ещё сравнение по предикату, притом можно сделать, что предикат в каждой строчке свой.
      А ещё добавить наконец поддержку: case(1,5) заместо: case 1: case 2: case 3: case 4: case 5:.
      Или добавить caseIn(List1), проверяющий принадлежность к листу.
      Ну и конечно:
      #define Break throw cccomboBreaker()
      Ответить

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