Есть ли шаблон, который называет управление злыми static_casts - PullRequest
2 голосов
/ 29 июня 2009

Следующий код является упрощенной версией того, что я использую для отправки событий. Существенным моментом является что есть аргумент static_cast в аргументе функтора шаблона, и другой класс делает убедитесь, что аргумент, переданный функтору, - это то, к чему приводит static_cast.

struct AbstractArg {
  virtual ~AbstractArg() { }
};

struct AbstractFunctor {
  virtual void operator()(AbstractArg*) const = 0;
  virtual ~AbstractFunctor() { }
};


namespace evil {

template<typename ArgT>
struct CastingFunctor :  AbstractFunctor {
  void operator()(AbstractArg* aarg) const
  {
    ArgT* arg = static_cast<ArgT*>(arg); // Danger!
    // ... do stuff with it
  }
};

} // namespace evil


class TypeidManager
{
public:
  typedef std::map<std::string, AbstractFunctor*> map_type;

  void dispatch(AbstractArg* arg) const
  {
    map_type::const_iterator it = typeid_map.find(std::string(typeid(*arg).name()));
    if (it != typeid_map.end())
    {
      AbstractFunctor* pFunctor = it->second;
      (*pFunctor)(arg);
    }
  };

  template<typename ArgT>
  void register_func( void (*fun_ptr)(ArgT*))
  {
    typeid_map.insert(std::make_pair(std::string(typeid(ArgT).name()),
                                     new evil::CastingFunctor<ArgT>));
  }

private:
  map_type typeid_map;
};

Есть ли название для этого шаблона?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 29 июня 2009

Это не анти-паттерн, это действительно полезная техника, часто используемая при стирании типов.

1 голос
/ 29 июня 2009

Я думаю, что это анти-паттерн, а не паттерн. Обычно вещи, которые вы хотите передать функторам через конструкцию typeid_map, исходят из общей иерархии наследования, и вместо этого вы используете динамический полиморфизм (= виртуальные методы). По сути, вы заново изобрели поиск в таблице виртуальных методов (очень неэффективно).

0 голосов
/ 29 июня 2009

Не то, что я знаю, хотя мы используем здесь нечто подобное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...