Есть ли преимущество / недостаток использования делегатов функций по сравнению с лямбдами в коллекции? - PullRequest
3 голосов
/ 10 декабря 2010

Я нахожусь на этом действительно скучном этапе разработки моей библиотеки, где я хочу создать класс на основе идентификатора сообщения Windows и аргументов WPARAM и LPARAM.Прототип таких функций тривиален:

boost::shared_ptr<EventArgs>(const UINT& _id, const WPARAM& _w, const LPARAM& _l);

Для каждого сообщения Windows у меня будет функция такого рода.

Теперь то, что я сейчас делаю, использует FastDelegate библиотека для моих делегатов.Они хранятся в карте следующим образом:

typedef fastdelegate::FastDelegate3<const UINT&, const WPARAM&, const LPARAM&, boost::shared_ptr<EventArgs> > delegate_type;
typedef std::map<int, delegate_type> CreatorMap;

И когда в сообщении Windows необходимо создать класс EventArg, полученный в результате, это простой случай поиска соответствующего делегата, его вызова и возвратаНедавно созданный экземпляр прекрасно содержится в shared_ptr.

boost::shared_ptr<EventArgs> make(const UINT& _id, const WPARAM& _w, const LPARAM& _l) const
 {
  MsgMap::const_iterator cit(m_Map.find(_id));
  assert(cit != m_Map.end());
  boost::shared_ptr<EventArgs> ret(cit->second(_w, _l));
  return ret;
 }; // eo make

Все работает нормально.Но потом я подумал, а не иметь вокруг себя всех этих делегатов, почему бы не воспользоваться лямбдами в C ++ 0x?Итак, я быстро прототипировал следующее:

typedef std::map<int, std::function<boost::shared_ptr<EventArgs>(const WPARAM&, const LPARAM&)> > MapType;
typedef MapType::iterator mit;

MapType map;
map[WM_WHATEVER] = [](const WPARAM& _w, const LPARAM& _l) { /* create appropriate eventargs class given parameters */ };
map[WM_ANOTHER] = ....;
// and so on

Еще раз, просто посмотреть и вызвать:

mit m = map.find(WM_PAINT);
boost::shared_ptr<EventArgs> e(m->second(_wParam, _lParam));
// dispatch e

Есть ли преимущество в использовании лямбд таким образом?Я знаю, что затраты на поиск нужного делегата / лямбды будут одинаковыми (так как оба типа карт имеют ключ int), но я стремлюсь посылать свои сообщения из wndProc в своем приятном C ++ дружественном способе, так какэффективно, насколько это возможно.У меня такое ощущение, что лямбды будут быстрее, но, к сожалению, мне не хватает опыта в понимании оптимизаций компилятора, чтобы принять решение по этому вопросу, поэтому мой вопрос здесь :) О, и в соответствии с темой вопроса, естькакие-нибудь ошибки / что-то, о чем я не думал?

1 Ответ

2 голосов
/ 10 декабря 2010

Здесь я вижу два реальных различия:

Первое - это способ хранения обратного вызова: либо fast-делегат, либо std :: function.Последний основан на boost :: function, и быстрые делегаты были специально разработаны, чтобы превзойти их.Однако std :: function соответствует стандарту, а быстрые делегаты - нет.

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

Если вам нужна грубая скорость - быстрые делегаты, вероятно, побеждают (но вам следует провести сравнительный анализ, если это аргумент), но если вы хотите удобочитаемости и стандартного соответствия, используйте std :: function и lambdas.*

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