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

    −22

    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
    class TFunctorMap
    	{
    	public:
    		typedef bool (*TFunctor)(const TSentenceList&, unsigned short &);
    	private:
    		std::map<char, TFunctor> _functorMap;
    	public:
    		TFunctorMap(void)
    		{
    			_functorMap.insert(std::make_pair('g', &RZC));
    			_functorMap.insert(std::make_pair('t', &STN));
    			_functorMap.insert(std::make_pair('d', &RTC));
    		}
    		TFunctor GetFunctor(const char Key)
    		{
    			if (_functorMap.find(Key) == _functorMap.end())
    				return NULL;
    			return _functorMap[Key];
    		}
    	};

    Запостил: Говногость, 16 Мая 2012

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

    • map<char, bool (*)(const TSentenceList&, unsigned short &)> m = {{'g', &RZC},{'t', &STN}, {'d', &RTC}};
      Ответить
      • unordered_map
        function<bool(...)>
        а еще обычный массив из N (<= CHAR_MAX) функторов (да хоть бы и указателей на функции) может быть выгоднее
        Ответить
        • Ну да, так тоже можно.
          http://liveworkspace.org/code/a2cb574468f590ed18c060e1c0b48587
          map<char, function<bool (const TSentenceList&, unsigned short &)>> m = {{'g', &RZC},{'t', &STN}, {'d', &RTC}};

          Правда, без function<...> будет оптимальнее.
          Только зачем unordered_map? Ну и с массивом будет не удобно.
          Ответить
          • http://liveworkspace.org/code/24c33d908cc7c4afe100305d735825bd
            map<char, bool (*)(const TSentenceList&, unsigned short &)> m=map_list_of('g', &RZC)('t', &STN)('d', &RTC);
            Ответить
    • Фи, двойной поиск в мапе в getFunctor.
      Ответить
      • Может здесь expression elimination сработает... хотя да, тупо.
        Ответить
        • Маловероятно. Скобки и find это разные вещи. find - чистая функция, а скобки имеют побочный эффект - внесение в мап элемента с дефолтным значением, если его не было.

          P.S. Кину камень в огород STLовцев: в Qt у мапа есть метод value, в который можно передать дефолтное значение. И код можно было бы переписать так:
          return _functorMap.value(Key, NULL)
          Ответить
          • А если NULL тоже элемент карты?
            Может быть, надо, чтобы value() возвращало не элемент, а ссылку на него, тогда NULL будет стопудов означать, что элемент не найден.
            Ответить
            • Функциональщики жить не могут без Maybe/Option имеено из-за таких проблем
              Ответить
              • >Maybe/Option
                Сейчас это есть уже во всех вменяемых языках.
                http://liveworkspace.org/code/16487076e4e2acb930388e448257cfb8
                #include <iostream>
                #include <map>
                #include <boost/optional.hpp>
                
                using namespace std;
                using namespace boost;
                
                optional<char> find_(const map<char, char>& m, char a)
                {
                   auto r=m.find(a);
                   if(r!=m.end()) 
                      return r->second;
                   else
                      return none; 
                }
                
                int main() {
                   map<char, char> m = {{'g', '5'},{'t', 45}, {'d', 5}};
                   cout<<find_(m, 'g').get()<<endl;//Сработает ассерт, если мы оказались слишком самоуверенны.
                   auto r = find_(m, 'y');
                   if(!r)
                      cout<< "y not found"<<endl;
                   return 0;
                }

                Только этот "паттерн" придумали не функциональщики, а сишники и ассемблерщики. Правда они для этого использовали некоторое значения, которое в контексте их типа запрещено или не имеет смысла (не входит в домен типа). Функциональщики лишь сделали их идею чуточку красивее.
                Ответить
                • > использовали некоторое значения, которое в контексте их типа запрещено или не имеет смысла
                  Это совсем разные вещи. Одно дело когда ты на уровне ТИПА объявляешь, что результата может и не быть, как минимум заставляя задуматься пользователя своего API, и совсем другое дело, когда ты возвращаешь -1 или null, который никак не форсируется для проверки.
                  К тому же, Maybe/Optional - это монада :)
                  Ответить
                  • >Это совсем разные вещи
                    Не видишь связи? Тогда ФП головного мозга.

                    >возвращаешь -1 или null, который никак не форсируется для проверки.
                    Дык кто мешает проверять? Сделать функцию, которая преобразует один тип в другой на уровне сишечки, при этом проверяя значение? Или даже не преобразовывая на ассемблере. Это ты привык, что все безопасно и ничего забыть нельзя, ибо компилятор скажет. В те времена не было такой возможности на ассемблере.
                    Да и NULL для поинтера часто проверяется автоматически, впрочем не так часто в те времена.

                    >Maybe/Optional - это монада
                    ФП головного мозга. Ещё скажи, что в коде выше тоже монада.
                    Ответить
                    • У меня нет никаких претензий к сишникам, я и сам долго писал на С, и до сих пор считаю этот язык отличным инструментом. Ассемблер, правда, только в универе изучал два семестра, в промышленности не пригодился.
                      Благо, сейчас часто надёжность и читаемость важнее скорости выполнения, а компиляторы стали умнее программиста.

                      И да, это совсем разные вещи. Ты возвращаешь уже не число, а контейнер, в котором, быть может, лежит число. Если у тебя Map<Int, Int>, то без Optional тебе сложно обойтись.
                      Ответить
                      • >Ты возвращаешь уже не число, а контейнер, в котором, быть может, лежит число.
                        Да капитан. Но этот тот же "паттерн".
                        Ответить
                        • "Паттерны" отличаются примерно так же, как можество, содержащее единичку, отличается от единички. Т.е. довольно существенно.

                          Плюс с Optional можно строить цепочки вычислений, каждое из которых может окончится неудачей, без утомительных проверок на нуллы и всякие минус единички.
                          Ответить
            • Ну value это просто краткая запись "если элемент не найден, то вернем дефолт". А если NULL элемент карты, и мне важно его отличать - придется юзать обычный find.

              >а ссылку на него
              А ссылка в с++ не может быть NULL, она по определению на что-то ссылается. Так что остаются указатель или итератор.
              Ответить

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