Suppose I have a function called subscribe()
that takes a callback handler, which will be called when the event is triggered.
Now, I have another version, called subscribe2()
. Everything is the same except that, when triggered, it needs to post it to an event queue. It is implemented using the original subscribe()
, with a helper funciton called helper()
. All it does is to bind the original handler and whatever additional arguments into a functor, and call postToEventQueue()
.
Now, I wonder if there's a way to eliminate the helper function, so that in subsribe2()
, I can somehow package the postToTaskQueue()
function and the original callback handler directly, and pass it to subscribe()
. The reason is that I have a lot of different handler types, and it is tedious and tiring to introduce helper function all over the place. Afterall, boost::bind is supposed to return a new function given the original function, right? I am trying to generate the helper function directly with boost::bind.
One attempt is to say
subscribe(boost::bind(boost::bind(postToTaskQueue, boost::bind(_1, _2)), cb, _1));
in subscribe2()
, but it doesn't work. Is it possible at all?
Please see detailed example code below. Thanks!
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
typedef boost::function<void(int)> SomeCallback;
typedef boost::function<void()> Task;
void handler(int i){
std::cout << "i=" << i <<std::endl;
}
void subscribe(SomeCallback cb)
{
cb(100); //just invoke the callback for simplicity
}
void postToTaskQueue(Task t)
{
t(); // just invoke the task for simplicity
}
void helper(SomeCallback cb, int i)
{
Task t = boost::bind(cb, i);
postToTaskQueue(t);
}
void subscribe2(SomeCallback cb)
{
subscribe(boost::bind(helper, cb, _1));
// this does not work..
// subscribe(boost::bind(boost::bind(postToTaskQueue, boost::bind(_1, _2)), cb, _1));
}
int main()
{
subscribe(boost::bind(handler, _1));
subscribe2(boost::bind(handler, _1));
}
I have no answer. However, I've played with this for over an hour:
boost::bind
boost::apply<>
boost::protect
Maybe, just maybe, a more experienced boost developer could take it from here:
The above prints
But, sadly, I can't seem to make this this thing parameterizing (as suggested should work in the documentation on composition using Nested Binds):
Here's a fully compiled demo showing the state of affairs: Live on Coliru