views:

342

answers:

3

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  A: 

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.

Emile Cormier
Ah, thanks. Should have known Boost already offers this.
Matt Olenik
+3  A: 

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)

Eugene
A: 

You should look into Sutter's Generalizing Observer

Gabriel