Since we're talking about C++ and not C, you should use std::function
. It's safer, and you can also use it to do more complex things like testing for existence, binding / currying...
#include <iostream>
#include <functional>
#using namespace std;
typedef function<void (void)> tVoidFunction;
typedef function<void (int)> tVoidFunctionTakingIntParameter;
typedef function<int (float)> tIntFunctionTakingFloatParameter;
void combinedFunction( tVoidFunction fvoid, tVoidFunctionTakingIntParameter fInt, tIntFunctionTakingFloatParameter fIntFromFloat){
if (fvoid) {
fvoid();
}
if (fInt && fIntFromFloat) {
static const float magicValue = 42.f;
int convertedValue = fIntFromFloat(magicValue);
fInt(convertedValue);
}
}
void helloWorld() {
cout << "Hello World" << endl;
}
int floatToInt(float f) {
return floor(abs(f));
}
void doSomethingWithAnInt(int i) {
cout << "doSomethingWithAnInt: " << i << endl;
}
...
void doWeirdThings() {
combinedFunction(helloWorld, doSomethingWithAnInt, floatToInt);
}
Ho illustrate why this is better than C-style function pointers, here are a couple (somewhat contrived) examples using std::bind
and a lambda to do some more interesting functional stuff:
struct Foo {
void doSomethingWithAnInt(int i) {
cout << "Foo instance @" << this << " got: " << i << endl;
}
}
int doSomethingWithTwoFloats(float f1, float f2) {
return floor(sqrt(abs(f1 + f2)));
}
...
void doWeirderThingsThanBefore() {
Foo someFoo;
auto someFooDoesSomethingWithAnInt = bind(&Foo:doSomethingWithAnInt, &someFoo);
static const float anotherMagicValue = 69.f;
auto doSomethingWithTheMagicValue = bind(&doSomethingWithTwoFloats, anotherMagicValue);
auto helloLambda = [](){
cout << "Hello, Lambda!" << endl;
};
combinedFunction(helloLambda, someFooDoesSomethingWithAnInt, doSomethingWithTheMagicValue);
}