Creating multicast events with std::tr1::function

2019-02-25 08:54发布

问题:

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?

回答1:

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)



回答2:

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.



回答3:

You should look into Sutter's Generalizing Observer