|
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
{
public:
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;
private:
// ...
};
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" );
// AND NOW IT GETS INTERESTING:
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
{
public:
void operator()() const;
private:
// 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?
Regards,
Andreas Huber
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk