[Function][bind]Using function to store arbitrary class and arbitrary function
Hello all, I have a quick question that I hope some of the experts on Function and Bind can answer. I'll give a quick précis of what I would like to do. We have an event system in our code. I would like to set this up so that any particular event can be 'attached' to arbitrary classes and functions in those classes. For example, a "Print" Event may need to call an arbitrary function in an arbitrary class (or a number of these). Therefore the event server needs to have a list of all these class/function pairs for each event type. I am pretty sure I can achieve that with a combination of boost::function and boost::bind. I see how I can use function if I know what the class type is..I would need to store the function and a this pointer in to the event server, but the this pointer would need to be to a specific type - that specified in the boost::function defn. Is there any way to make the this pointer of an arbitrary type such that the function call can be made to any arbitrary function in any arbitrary class? Sorry, I don't have a code snippet to help explain - that's what I'm trying to figure out!! There may well be better ways of doing what we need - those thoughts also gratefully received (nb. Working in a multithreaded environment, so boost:signals may not be appropriate) James This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.
Hughes, James wrote:
Hello all,
I have a quick question that I hope some of the experts on Function and Bind can answer. I'll give a quick précis of what I would like to do.
We have an event system in our code. I would like to set this up so that any particular event can be 'attached' to arbitrary classes and functions in those classes. For example, a "Print" Event may need to call an arbitrary function in an arbitrary class (or a number of these). Therefore the event server needs to have a list of all these class/function pairs for each event type.
I am pretty sure I can achieve that with a combination of boost::function and boost::bind. I see how I can use function if I know what the class type is..I would need to store the function and a this pointer in to the event server, but the this pointer would need to be to a specific type - that specified in the boost::function defn. Is there any way to make the this pointer of an arbitrary type such that the function call can be made to any arbitrary function in any arbitrary class?
Sorry, I don't have a code snippet to help explain - that's what I'm trying to figure out!!
There may well be better ways of doing what we need - those thoughts also gratefully received (nb. Working in a multithreaded environment, so boost:signals may not be appropriate)
Sounds like you're labouring under a misunderstanding of how the whole function type works. The this pointer will be bound into the lambda created by the boost::bind function (I always use boost::lambda::bind as I don't really understand the difference between them and I always think of this stuff in terms of lambdas). Say that the event comprises of a couple of parameters sent to a function. We can use something like a mouse click as an example: string do_click( int x, int y ); The event dispatcher is going to do this sort of thing: result = do_click( theX, theY ); A boost function that looks like that will be this: boost::function< string ( int, int ) > event_handler; We can tie the global function into it like this: event_handler = boost::function< string ( int, int ) >( do_click ); So far so good. But what if the do_click is a member of a mouse object? You might have something like this: Mouse mouse; event_handler = boost::lambda::bind( &Mouse::do_click, mouse, boost::lambda::_1, boost::lambda::_2 ); (There is a complication to do with the lifetime of mouse here that I'm ignoring, but you won't be able to. I tend to bind a boost::shared_ptr if needed.) As you can see it doesn't matter what the other parameters are as they fall out once you've created the lambda. Either thing can be assigned to the event_handler because it's type is a function that takes two ints and returns a string. Anything that can be bound and turned into this signature can be assigned to it. What you are doing relates to concepts of type transformations common in functional programming languages. If you get hold of Haskell and go through a couple of tutorials then the concepts will become much more familiar. The C++ syntax is much more baroque and verbose, but the concepts are much the same. The operation that you're after is "partial application" and is closely related to "currying". Hope this answers the correct question :-) K
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Kirit Sælensminde Sent: 14 June 2007 10:20 To: boost-users@lists.boost.org Subject: Re: [Boost-users] [Function][bind]Using function to store arbitrary class and arbitrary function
Hello all,
I have a quick question that I hope some of the experts on Function and Bind can answer. I'll give a quick précis of what I would like to do.
We have an event system in our code. I would like to set
Hughes, James wrote: this up so that any particular event can be 'attached' to arbitrary classes and functions in those classes. For example, a "Print" Event may need to call an arbitrary function in an arbitrary class (or a number of these). Therefore the event server needs to have a list of all these class/function pairs for each event type.
I am pretty sure I can achieve that with a combination of
boost::function and boost::bind. I see how I can use function if I know what the class type is..I would need to store the function and a this pointer in to the event server, but the this pointer would need to be to a specific type - that specified in the boost::function defn. Is there any way to make the this pointer of an arbitrary type such that the function call can be made to any arbitrary function in any arbitrary class?
Sorry, I don't have a code snippet to help explain - that's
what I'm trying to figure out!!
There may well be better ways of doing what we need - those
thoughts
also gratefully received (nb. Working in a multithreaded environment, so boost:signals may not be appropriate)
Sounds like you're labouring under a misunderstanding of how the whole function type works. The this pointer will be bound into the lambda created by the boost::bind function (I always use boost::lambda::bind as I don't really understand the difference between them and I always think of this stuff in terms of lambdas).
More of a complete lack of knowledge than a misunderstanding!!!
Say that the event comprises of a couple of parameters sent to a function. We can use something like a mouse click as an example:
string do_click( int x, int y );
The event dispatcher is going to do this sort of thing:
result = do_click( theX, theY );
A boost function that looks like that will be this:
boost::function< string ( int, int ) > event_handler;
We can tie the global function into it like this:
event_handler = boost::function< string ( int, int ) >( do_click );
So far so good. But what if the do_click is a member of a mouse object? You might have something like this:
Mouse mouse; event_handler = boost::lambda::bind( &Mouse::do_click, mouse, boost::lambda::_1, boost::lambda::_2 );
(There is a complication to do with the lifetime of mouse here that I'm ignoring, but you won't be able to. I tend to bind a boost::shared_ptr if needed.)
That what I needed. Thanks. <snip> James This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.
Hughes, James wrote:
Hello all,
I have a quick question that I hope some of the experts on Function and Bind can answer. I'll give a quick précis of what I would like to do.
We have an event system in our code. I would like to set this up so that any particular event can be 'attached' to arbitrary classes and functions in those classes. For example, a "Print" Event may need to call an arbitrary function in an arbitrary class (or a number of these). Therefore the event server needs to have a list of all these class/function pairs for each event type.
Bind and Function were meant to work together to do this. See, for example: http://www.boost.org/libs/bind/bind.html#with_boost_function Note that a "function" object can only target only thing. You can create a container of "function" objects if you want to be able to call several different things, or just use the Boost.Signals library which was designed for this purpose. - Doug
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of Hughes, James Sent: Thursday, June 14, 2007 4:24 AM To: boost-users@lists.boost.org Subject: [Boost-users] [Function][bind]Using function to store arbitrary class and arbitrary function
There may well be better ways of doing what we need - those thoughts also gratefully received (nb. Working in a multithreaded environment, so boost:signals may not be appropriate)
[Nat] I'll echo Doug in saying that Boost.Signal was designed for use cases like yours. We use Boost.Signal very successfully in a mixed C++ and Python environment. Ours is single-threaded. Please have a look at the mail archive as well: there has been a recent fairly extensive discussion about a thread-safe implementation of (a close approximation of) the Boost.Signal interface.
participants (4)
-
Douglas Gregor
-
Hughes, James
-
Kirit Sælensminde
-
Nat Goodspeed