Creating multicast events with std::tr1::function

2019-02-25 08:38发布

I'm attempting to create C#-like multicast delegates and events using features from TR1. Or Boost, since boost::function is (mostly) the same as std::tr1::function. As a proof of concept I tried this:

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);
  }
 }
};

Which works, sort of. The line callbacks.remove(func) does not. When I compile it, I get the following error:

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

Which is caused by line 1194 of the list header, which is in the remove function. What is causing this?

3条回答
狗以群分
2楼-- · 2019-02-25 08:57

If you're you're looking for multicast delegates in C++, your best bet would be Boost.Signals2. You can also use Boost.Bind to make it possible to use member functions for callbacks.

You can look at my example here for simple usage of Boost.Signals and Boost.Bind.

Boost.Signal provides lifetime management facilities to ensure that events are not published to subscribers that no longer exist.

查看更多
The star\"
3楼-- · 2019-02-25 09:07

I think this is exactly same problem: comparing-stdtr1function-objects

(basically you can't compare functors, that's why erase or anything using operator== won't work)

查看更多
Anthone
4楼-- · 2019-02-25 09:08

You should look into Sutter's Generalizing Observer

查看更多
登录 后发表回答