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

    +1

    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
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    #include <iostream>
    #include <map>
    
    template <typename T1, typename T2, typename F>
    void operator ^= (std::map<T1,T2> &m, F func) {
        for (typename std::map<T1,T2>::iterator i = m.begin();  i != m.end(); ) {
            if (func(i))
                i = m.erase(i);
            else
                ++i;
        }
    }
    
    template <typename T1, typename T2>
    void operator ^= (std::map<T1,T2> &m, T2 value) {
        for (typename std::map<T1,T2>::iterator i = m.begin();  i != m.end(); ) {
            if (value == i->second)
                i = m.erase(i);
            else
                ++i;
        }
    }
    
    int main() {
        std::map<int,bool> m = {
            {0,false},
            {1,true},
            {2,false},
            {3,true},
            {4,false},
            {5,true},
            {6,false},
            {7,true},
            {8,false},
            {9,true},
            {10,false}
        };
    
        for (auto i = m.begin(); i != m.end(); ++i)
            std::cout << "{" << i->first << "," << i->second << "} ";
        std::cout << std::endl;
    
        m ^= false;
        m ^= [](auto &i) { return i->first == 5; };
    
        for (auto i = m.begin(); i != m.end(); ++i)
            std::cout << "{" << i->first << "," << i->second << "} ";
        std::cout << std::endl;
    }

    Для std::vector'a запись не особо-то кошерная:

    std::vector<int> v = {1,2,3,4,5};
    v.erase(std::remove_if(v.begin(),v.end(),[](int &i){ return i <= 3;}), v.end());
    А для std::map даже такого не придумали. Пора исправлять

    Запостил: Antervis, 10 Мая 2016

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

    • Когда-то читал, что нельзя определять операторы для шаблонов из стд, если эти шаблоны не зависят от пользовательского типа. А теперь не могу найти ничего про это. Реквестирую в тред крестушков, знающих стандарт наизусть.
      Ответить
    • на что только не пойдут люди, чтобы не писать 2 строчки простого понятного кода, который удаляет и делает прочие дрочения с контейнером

      если по делу

      1)
      > А для std::map даже такого не придумали. Пора исправлять
      я тебе даже больше скажу - удалять из std::map по value вместо key уже так себе идея - если тебе надо делать это часто, есть bimap контейнеры

      2) operator ^= это пиздец, не надо так, мне не понятно что там скрывается - значит, никому не понятно

      3) std::map<T1,T2> - будешь писать для каждого контейнера?
      лучше напиши ещё несколько уровней шаблонов, чтобы эффективно удалять из контейнера, где удаление из середины дешево, так и из контейнера, где удаление из середины дорого,

      заодно напиши хелпер, который будет уметь сравниваться с понятным ему iterator::reference, используя магические вещи типа _ для обозначения "подойдет любое" - чтобы получилось
      using my::_;
      my::remove(somemapcontainer, my::pair_value(_, false));
      вот тогда шаблоноёбство заиграет новыми красками
      а так это детский сад какой-то
      Ответить
      • показать все, что скрыто> на что только не пойдут люди, чтобы не писать 2 строчки простого понятного кода, который удаляет и делает прочие дрочения с контейнером
        Не две, а шесть. Встречать их повсеместно надоедает.
        > я тебе даже больше скажу - удалять из std::map по value вместо key уже так себе идея
        куда важнее удаление по fn(value)
        > есть bimap контейнеры
        Это надо буст тянуть, а всем читающим код разбираться что такое bimap
        > operator ^= это пиздец, не надо так
        ок
        > мне не понятно что там скрывается - значит, никому не понятно
        ЧСВ over 9000
        Ответить
        • > Это надо буст тянуть, а всем читающим код разбираться что такое bimap
          не знать, что такое буст, или бояться header-only библиотек могут позволить себе только qt-профессионалы, которым и c++ и STL в тягость

          > куда важнее удаление по fn(value)
          ок, boost.multiindex

          > Не две, а шесть
          или одна:
          for (auto i = mymap.begin(); i != mymap.end(); i = func(i) ? mymap.erase(i) : i+1);


          > Встречать их повсеместно надоедает.
          поэтому функция с говорящим именем круче оператора
          ^= читается как "поксорь все элементы контейнера с указанным значением"
          Ответить
        • > > я тебе даже больше скажу - удалять из std::map по value вместо key уже так себе идея

          > куда важнее удаление по fn(value)

          и на сколько часто ты это делаешь?
          Ответить
          • иногда доводится
            Ответить
            • если ты только заради "иногда" какую-то нестандартную фигню поришь?

              напиши лучше простую человеческую функцию.
              Ответить
        • > ЧСВ over 9000
          Это не ЧСВ, а просто опыт работы в команде... Вот сам же потом забудешь через год, что делает оператор ^ для мапов...

          Пиши код так, как будто сопровождать его будет склонный к насилию психопат.
          Ответить
          • нахожу очевидным, что никто не будет один и тот же код не буду выкладывать на говнокод и в продакшн одновременно...

            его и так мне сопровождать
            Ответить
      • > _
        Пролог-style
        Ответить
        • ну дык недавно www.xxx постил в другом треде
          я адаптировал
          Ответить
        • Ещё в бусте всякие _1, _2 как плейсхолдеры юзают.
          Ответить
        • Программист на Прологе может на любом языке писать, как на Прологе.
          Ответить
      • > operator ^= это пиздец
        Угу. Если уж шило в жопе и хочется именно оператор, я бы для удаления элементов выбрал -=.
        Ответить
      • 4) void operator ^= (std::map<T1,T2> &m, T2 value) {
        Ответить
    • что-то заминусовали человека в хлам
      что за нетерпимость
      стыдно, товарищи
      Ответить

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