Создание многоадресных событий с помощью std :: tr1 :: function (или boost :: function) - PullRequest
3 голосов
/ 09 февраля 2010

Я пытаюсь создать C # -подобные многоадресные делегаты и события, используя функции из TR1. Или Boost, так как boost :: function (в основном) такой же, как std :: tr1 :: function. В качестве доказательства концепции я попробовал это:

template<typename T1>
class Event
{
private:
 typedef std::tr1::function<void (T1)> action;
 std::list<action> callbacks;

public:

 inline void operator += (action func)
 {
  callbacks.push_back(func);
 }

 inline void operator -= (action func)
 {
  callbacks.remove(func);
 }

 void operator ()(T1 arg1)
 {
  for(std::list<action>::iterator iter = callbacks.begin();
   iter != callbacks.end(); iter++)
  {
   (*iter)(arg1);
  }
 }
};

Что работает, вроде. Строка callbacks.remove(func) не имеет. Когда я его компилирую, я получаю следующую ошибку:

error C2451: conditional expression of type 'void' is illegal

Это вызвано строкой 1194 заголовка list, который находится в функции remove. Что вызывает это?

Ответы [ 3 ]

5 голосов
/ 09 февраля 2010

Если вы ищете многоадресных делегатов в C ++, лучшим вариантом будет Boost.Signals2 . Вы также можете использовать Boost.Bind , чтобы сделать возможным использование функций-членов для обратных вызовов.

Вы можете посмотреть мой пример здесь для простого использования Boost.Signals и Boost.Bind.

Boost.Signal предоставляет средства управления временем жизни, чтобы гарантировать, что события не будут публиковаться для подписчиков, которые больше не существуют.

4 голосов
/ 09 февраля 2010

Я думаю, что это точно такая же проблема: comparing-stdtr1function-objects

(в принципе вы не можете сравнивать функторы, поэтому стирание или что-либо с использованием оператора == не сработает)

0 голосов
/ 14 февраля 2010

Вы должны взглянуть на обобщающий наблюдатель Саттера

...