This is just a small tip on how to define a vector of function pointers in C++ and how to call functions stored in it:
#include <vector>
#include <iostream>
typedef int (*fptr)(int, int);
int foo(int a, int b) { return a + b; }
int bar(int a, int b) { return a * b; }
int main()
{
std::vector<fptr> f;
f.push_back(foo);
f.push_back(bar);
std::cout << f[0](2, 3)
<< f[1](2, 3)
<< std::endl;
return 0;
}
That’s it. Next, this example could be extend to replace old-fashion function pointers with function objects.
Cute. Hadn’t thought of using vectors with functions. You could create semi-self-modifying code that way. Might also make some interesting “art code”… qsort the vector one way and you get this result, qsort another way and get a different result…
Yes, it’s pretty simple and even powerful. As you said, it can be used to store different strategies (algorithms) for the same set of input parameters. Replacing std::vector with std::map you can have a simple solution of map of events and handlers, and so on.
Hello, I try to implement something like you mentioned (map of events). However, I need vector/map for f. pointers, which differ in argument lists (you know – one map for (int,int), (int,int,int,string) and so on). can you advice me something?
Boost.Function and Boost.Bind can help:
Updated on March 12, 2010
The sample in action:
Another approach is to use Command pattern or its variants. It is have a base class for your messages and common interface to execute.
Your example using Boost.Function and Boost.Bind doesn’t seem to work. Could you possibly check the code again and specify the template arguments for boost::function and std::map? Also, fun_t is not used anywhere in the example, how do you create boost::function objects from the functions foo, goo and bar?
Thanks!
Hi Mathis,
The code was an untested blueprint and also < and > was eaten by HTML engine. I have updated the code in my comment above with complete, compilable and runnable example. I hope it helps.
Hi Mateusz
Thanks a lot, I’m quite impressed that this is possible.
Can you think of a way to make this work with functions that have different return types? Unfortunately, I can’t use the function parameters as return values (by using references) because I need to directly use the return value as a parameter for another function call.
Hi Mathis,
I doubt it’s feasible to bind functions with different return types really, though I’d be interested to see solution if it’s possible, myself. Perhaps, you could try to overcome this limitation with boost::lambda::bind or use boost::any as common return type holder. I’m not sure it makes much sense to have different return types here, as it seems the whole construction based on map does not give any benefits. You’d rely on checking type anyway.
Good, Great.
Short and well explaned.