Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: How do I pass a function(without knowing its parameters) to another function?

I'm trying to create a function that will store and repeat another function given as a parameter for a specific amount of time or repeats given. But when you want to pass a function as a parameter you have to know all of its parameters before hand. How would I do if I wanted to pass the function as one parameter, and the parameters as another?

void AddTimer(float time, int repeats, void (*func), params); // I know params has no type and that (*func) is missing parameters but it is just to show you what I mean

Thanks in advance

like image 984
Ninja Avatar asked Jan 29 '11 15:01

Ninja


1 Answers

The best that you can do is use std::function or boost::function as argument, together with std::bind or boost::bind to, well, bind the arguments with the function:

void foo() { std::cout << "foo" << std::endl; }
void bar( int x ) { std::cout << "bar(" << x << ")" << std::endl; }
struct test {
   void foo() { std::cout << "test::foo" << std::endl; }
};
void call( int times, boost::function< void() > f )
{
   for ( int i = 0; i < times; ++i )
      f();
}
int main() {
   call( 1, &foo );                   // no need to bind any argument
   call( 2, boost::bind( &bar, 5 ) );
   test t;
   call( 1, boost::bind( &test::foo, &t ) ); // note the &t
}

Note that there is something inherently wrong with passing a fully generic function pointer: how do you use it? How would the body of the calling function look like to be able to pass an undefined number of arguments of unknown types? That is what the bind templates resolve, they create a class functor that stores the function pointer (concrete function pointer) together with copies of the arguments to use when calling (note the &t in the example so that the pointer and not the object is copied). The result of the bind is a functor that can be called through a known interface, in this case it can be bound inside a function< void() > and called with no arguments.

like image 152
David Rodríguez - dribeas Avatar answered Sep 30 '22 11:09

David Rodríguez - dribeas