Can boost :: bind be used to efficiently concatenate functions?

Suppose I have a boost :: function with an arbitrary signature of type CallbackType .

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

I am open to any potential solution, but here ...

... A hypothetical example using some magic pattern:

 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; } 
+6
c ++ boost callback functor bind
source share
2 answers

Boost already provides a way to create a sequence of related functions. Use the Lambda comma operator .

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

This will create a new object functor. When you call this functor with three arguments, it in turn calls mc.alert() before passing those arguments to doIt . Brackets are important.

For my example above, you need alert be const . If it should be non-constant, then either pass a pointer to mc or wrap it with boost::ref(mc) . And you will need to use Boost.Lambda bind , not Boost.Bind; the latter is incompatible with lambda functions that combine operators (in particular, a comma).

+8
source share
 template< class Callback > struct pre_caller { Callback c; pre_caller( Callback in_c ) : c( in_c ) {} void alert() {} // or an instance of a functor operator() { alert(); c(); } template< class T1 > operator( T1 a ) // not sure if/what qualification to add to a { alert(); c( a ); } // or whether to attempt to obtain from // function_traits<Callback>? template< class T1, class T2 > operator( T1 a, T2 b ) { alert(); c( a, b ); } template< class T1, class T2, class T3 > operator( T1 a, T2 b, T3 c ) { alert(); c( a, b, c ); } // ad nauseam... and I mean nausea, maybe read up on Boost Preprocessor. }; 

Boost Bind uses a lot of preprocessor hackers for its varied voodoo, and, unfortunately, I don't think it provides a template or tools for fixing headers, which is essentially what it is.

+1
source share

All Articles