|
Boost : |
From: David Abrahams (david.abrahams_at_[hidden])
Date: 2001-11-17 13:40:00
The design I've seen which works nicely... I suppose couldn't use
boost::function<> either. Actually, this design requires the use of mix-ins,
which I can imagine some people might be unhappy with.
The idea is that every message identifier is essentially a member function
pointer to a virtual function of a mix-in class, all of which inherit
virtually from Subscriber. The broadcast mechanism dynamic_casts each
Subscriber to the class type of the member function pointer, and if
successful, calls through the function pointer to send the message. This
scheme preserves object identity in the Publisher's list of Subscribers, so
that removing a Subscriber (e.g. when it is destroyed) is trivial.
I can see now that this scheme prevents many useful programs. For example, a
Subscriber might want to tell the publisher, "call this member function with
the 1 bound to the first argument". I guess that tying message identity to a
member function pointer is rather limiting. I wonder what a design using
boost::function<> would look like? Not having any way to test whether an
arbitrary instantiation of boost::function<> can be called with a given set
of arguments makes this problem look hard to me...
-Dave
----- Original Message -----
From: <spam2002_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Saturday, November 17, 2001 12:25 PM
Subject: [boost] Using boost::function for publish-subscribe???
> 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
>
>
>
> Info: http://www.boost.org Unsubscribe:
<mailto:boost-unsubscribe_at_[hidden]>
>
> Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
>
>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk