Search code examples
c++function-pointersfunction-parameter

C++ function parameters wont compile


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(*)?


Solution

  • Function pointers can be tedious to work with, this is where typedefs 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.