So I have a function with the prototype
double Solution::bisect
(
double xLeft,
double xRight,
double epsilon,
double f(double x, EquCoeffs coeffsStruct),
bool &error
);
where function f
is prototyped like this
double Solution::f(double x, EquCoeffs coeffsStruct);
The error I am getting in Visual Studio is argument of type "double(Solution::*)(double x, Solution::EquCoeffs coeffsStruct)" is incompatible with parameter of type "double(*)(double x, Solution::EquCoeffs coeffsStruct)"
which occurs when I try to call bisect(xLeft, xRight, epsilon, f, error);
where xRight
xLeft
epsilon
, are type double
and error
is type bool
.
Why won't this compile? I'm not sure I understand the error. How is a double(Solution::*)
different than double(*)
?
Function pointers can be tedious to work with, this is where typedef
s come in handy:
typdef R (*FREE_FUNC)(ARGS);
makes FREE_FUNC
an alias for function pointers of type R(*)(ARGS)
, ie functions with ARGS
parameter and R
return type. It may look a bit strange, that the new name appears in the middle on the typdef. However, everywhere else using function pointers is then much nicer, for example
typedef void (*LOGGER)(R,ARGS);
R decorate(FREE_FUNC func,LOGGER logger,ARGS args){
R result = func(args);
logger(result,args);
return result;
}
Member function pointers are different, because you need an object to call them:
struct Foo {
void foo(){std::cout << "moo \n";}
void moo(){std::cout << "xyz \n";}
};
typedef void (Foo::*FOO_MEMBER_FUNC)();
void fooCaller(Foo f,FOO_MEMBER_FUNC mf){
(f.*mf)();
// ... or ...
Foo* f_ptr = &f;
(f_ptr->*mf)();
}
int main() {
FOO_MEMBER_FUNC foo_ptr = &Foo::foo;
FOO_MEMBER_FUNC moo_ptr = &Foo::moo;
Foo f;
fooCaller(f,foo_ptr);
fooCaller(f,moo_ptr);
}
I should also mention, that there are better ways to pass functions. You can take a look at std::function.