Boost logo

Boost :

From: spam2002_at_[hidden]
Date: 2001-11-17 12:25:11

I would like to use boost::function within a publish-subscribe scheme
as follows (code does not compile):

class ForecastPublisher
    typedef boost::function< void, const std::string & > Subscriber;

    void AddSubscriber( const Subscriber & subscriber );
    void RemoveSubscriber( const Subscriber & subscriber );

    // sends forecast to all currently registered subscribers
    void Publish( const std::string & forecast ) const;

    // ...

void Subscriber1( const std::string & forecast );
void Subscriber2( const std::string & forecast );

int main()
  ForecastPublisher publisher;
  publisher.AddSubsriber( &Subscriber1 );
  publisher.Publish( "bla bla" ); // only Subscriber1() is called

  publisher.AddSubscriber( &Subscriber2 );
  // Subscriber1() and Subscriber2() are called
  publisher.Publish( "More bla bla" );


  publisher.RemoveSubsriber( &Subscriber1 );
  // only Subscriber2() is called
  publisher.Publish( "More bla bla" );

The problem lies in the fact that it is impossible to write
RemoveSubscriber(), because there is no such thing as operator== or
operator!= for two boost::function objects.
Providing equality operators for the current boost::function
implementation does not seem to be possible either, because there is
no way to compare two boost::function objects containing the same
third "foreign" function object:

class MyFunctor
    void operator()() const;

    // may have state ...

int main()
  // given that boost::function provides equality operators,
  // how exactly do you implement comparison for f1 and f2?
  // what result should operator== yield in this case? true?
  // false?
  boost::function< void > f1 = MyFunctor();
  boost::function< void > f2 = MyFunctor();

  std::cout << ( f1 == f2 );

This fact (and because I think using functors for publish-subscribe
is a good idea) forced me to write my own functor library, which
implements almost the same functionality as boost::function,
boost::bind and boost::mem_fn together (with quite a different
interface though and without providing automatic conversion
from "foreign" functors of course). However, given the low-level
nature of functors implementing them yourself is as undesirable as
writing your own std::vector implementation. This leads to the
following questions:

0. Am I missing something??
1. What was the design rationale behind prefering the possibility to
adapt "foreign" function objects over the possibility to use
boost::function in publish-subscribe schemes? IMHO, the latter is
probably needed by more programmers.
2. As mentioned above, there seems to be no way to extend
boost::function, boost::bind and boost::mem_fn to provide equality
operations AND automatic conversions from "foreign" functors. What's
worse, with equality operations, the functionality of boost::function
and boost::bind seems to be no longer orthogonal. Any ideas anyone?


Andreas Huber

Boost list run by bdawes at, gregod at, cpdaniel at, john at