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

    +54

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    Exchange::Params pars = rawParams;
    for(Exchange::Params::const_iterator i = rawParams.constBegin(); i!= rawParams.constEnd(); i++){
        LOGN() << "Work with " << i.key() << "=" << i.value();
        if(m_specific.contains(i.key())){
            pars[i.key()] =
                (this->*m_specific.value(i.key())) (i.value());     //черная магия :)
        }
    }

    Наследие из большого рабочего проекта.
    Чтобы сохранить ясность ума на весь день решил не пытаться понять что оно делает.

    Запостил: FlySnake, 08 Сентября 2014

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

    • auto func = m_specific.value(i.key());
      (this->*func)(i.value());

      Так конечно будет понятнее, но все же, причем тут черная магия в исходном тексте?
      Ответить
    • > что оно делает
      Да ничего особо сложного. Для каждого из параметров смотрит, требует ли он особой (specific) обработки, и если да - заменяет значение на результат его обработки соответствующей функцией.
      Ответить
    • Это не черная, а коричневая магия. Еще постинкремент итератора.
      Ответить
      • > Еще постинкремент итератора.
        Всем похуй на эти копейки, ибо дальше еще хуже - 2 раза один и тот же ключ в мапе ищут (contains() и value()).
        Ответить
        • Ключ в мапе искать не так уж и накладно (как скажем, в списке). Тем более что тут может быть и хеш.
          Ответить
          • Всяко накладней, чем постинкремент итератора от той же мапы.

            А т.к., скорее всего, это загрузка конфига при старте проги - то на оптимизации вообще насрать...
            Ответить
            • > то на оптимизации вообще насрать...
              поэтому добавим ещё туеву хучу нагрузочных циклов
              Ответить
              • Ну что там за итератор такой, что есть ощутимая разница между a++ и ++a? Я хоть и байтоёб, но не понимаю, чего все с этим преинкрементом носятся как с писаной торбой...
                Ответить
                • >но не понимаю, чего все с этим преинкрементом носятся как с писаной торбой...
                  Мелочь.
                  В большинстве случаев вменяемый компилятор высрет побайтово идентичный код.
                  Ответить
                  • > побайтово идентичный код
                    Ага. Потому что в 99.999% случаев постинкремент запилен как backup - increment - return copy, компилятор видит, что копия никому нахер не сдалась, и выпиливает ее вместе с бекапом.

                    Вся эта история чем-то напоминает пыхооптимизации: ' быстрее ", интерполяция быстрее подготовленных запросов и т.п.
                    Ответить
                    • > компилятор ... выпиливает

                      Если копирование имеет побочные эффекты, как он сможет это сделать?
                      Встречаются довольно жирные итераторы с нетривиальным состоянием внутри.
                      Ответить
                      • > Встречаются довольно жирные итераторы с нетривиальным состоянием внутри.
                        Т.е., например, i/o итератор, который в себе хранит всю текущую запись? Ну ок, резонно.

                        P.S. Хотя из побочных действий при копировании тут будет разве что выделение памяти из кучи.
                        Ответить
                        • А мы хотим выделять память из кучи на каждом инкременте?
                          Да и реализация конструктора копирования может быть скрыта от компилятора, если итератор не шаблонный.
                          Ответить
                          • > на каждом инкременте
                            Я про такой случай - вдруг итератор выделил память под некие структуры данных в своём конструкторе, а в инкременте просто помещает в них новые значения. Вот такой итератор действительно дороговато копировать.
                            Ответить
                            • > итератор выделил память под некие структуры данных в своём конструкторе, а в инкременте просто помещает в них новые значения.

                              Удивительно, но говорю о том же самом. Так работает, например, std::istream_iterator<T>.
                              Ответить
                              • > Удивительно, но говорю о том же самом.
                                > А мы хотим выделять память из кучи на каждом инкременте?
                                А, всё, я не так распарсил эту фразу. Подумал, что она относится к внутренней логике самого инкремента, а не к последствиям копирования в постинкременте.
                                Ответить
                              • P.S. Обитатели ГК настолько суровы, что могут спорить имея одинаковую точку зрения.
                                Ответить
                      • P.S. Кстати, а итераторы с дорогим конструктором копирования вообще имеют смысл? Ведь большинство stl алгоритмов, емнип, принимает их по значению, а не по ссылке.
                        Ответить
                        • Да, итераторы всегда и везде передаются по значению. От этого иногда плющит, но смысл в этом есть.
                          Ответить
                          • > всегда и везде
                            Я пару раз передавал по неконстантной ссылке.
                            Ответить
                            • Не канонично :)
                              В стандартной библиотеке везде.
                              Ответить
                              • Мне лень было возвращать пару итераторов на ужатый range, поэтому тупо поменял их через ссылки...
                                Ответить

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