C function pointers with C++11 lambdas

Using a void* is typical of C callback interfaces to pass some “state” to the function. However, std::function does not need this because std::function supports “stateful functions”. So, you could do something like this:

double Integrate(
          std::function<double(double)> func,
          double a, double b)
{
    typedef std::function<double(double)> fun_type;
    :::
    F.function = [](double x, void* p){
        return (*static_cast<fun_type*>(p))(x);
    };
    F.params = &func;
    :::
}

and store a reference to the parameter vector as part of the functor that will be encapsulated in the std::function object or do something like this:

void Another_function()
{
    double m = 2;
    double b = 3;
    auto func = [&](double x){return m*x+b};
    auto r1 = Integrate(func,0,3);
    :::
}

However, this solution would use rather many indirections. GSL would invoke your lambda. Your lambda would invoke the std::function<>::operator() which in turn would inwoke some kind of virtual function that is used for type erasure which would in turn invoke the actual computation.

So, if you care about performance, you could get rid of a couple of layers there, specifically std::function. Here’s a another approach with a function template:

template<class Func>
double Integrate(
          Func func,
          double a, double b)
{
    :::
    F.function = [](double x, void* p)->double{
        return (*static_cast<Func*>(p))(x);
    };
    F.params = &func;
    :::
}

I guess I would prefer this over the std::function solution.

Leave a Comment