Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use boost::bind to effectively concatenate functions?

Assume that I have a boost::function of with an arbitrary signature called type CallbackType.

  • Is it possible to use boost::bind to compose a function that takes the same arguments as the CallbackType but calls the two functors in succession?

I'm open to any potential solution, but here's a...

...Hypothetical example using some magic template:

Template<typename CallbackType>
class MyClass
{
    public:
        CallbackType doBoth;

        MyClass( CallbackType callback )
        {
            doBoth = bind( magic<CallbackType>, 
                             protect( bind(&MyClass::alert, this) ),   
                               protect( callback )                    );
        }

        void alert()
        {
            cout << "It has been called\n";
        }
};

void doIt( int a, int b, int c)
{
    cout << "Doing it!" << a << b << c << "\n";
}

int main()
{
    typedef boost::function<void (int, int, int)> CallbackType;

    MyClass<CallbackType> object( boost::bind(doIt) );

    object.doBoth();

    return 0;
}
like image 953
Catskul Avatar asked Apr 29 '10 21:04

Catskul


1 Answers

Boost already provides a way to create a sequence of bound functions. Use Lambda's comma operator.

using namespace boost::lambda;
MyClass mc;
CallbackType object = (bind(&MyClass::alert, mc), bind(doIt, _1, _2, _3));
object(1, 2, 3);

That will create a new functor, object. When you invoke that functor with three arguments, it will in turn call mc.alert() before passing those arguments to doIt. The parentheses are important.

For my example above to work, you'd need alert to be a const function. If it needs to be non-const, then either pass a pointer to mc, or wrap it with boost::ref(mc). And you'll need to use Boost.Lambda's bind rather than Boost.Bind's; the latter isn't compatible with Lambda's function-combining operators (comma, in particular).

like image 172
Rob Kennedy Avatar answered Oct 25 '22 17:10

Rob Kennedy