Thought I would add my lambda-based attempts at this.
It works fine in principle:
// function we want to pass to GSL
double a_squared(double a) { return a*a; }
typedef double gsl_function_type(double, void*); // convenient typedef
// lambda wrapping a_squared in the required interface: we can pass f directly to GSL
gsl_function_type* f = [](double x, void*) { return a_squared(x); };
But we'd really like to write a method to apply this to any given function. Something like this:
gsl_function_type* convert(double (*fn)(double))
{
// The lambda has to capture the function pointer, fn.
return [fn](double x, void*) { return fn(x); };
}
However, the lambda now has to capture the pointer fn
, because fn
has automatic storage duration (in contrast to the static function a_squared
in the first example). This doesn't compile because a lambda which uses a capture cannot be converted to a simple function pointer, as required by the return value of our function. In order to be able to return this lambda we'd have to use a std::function
, but there's no way to get a raw function pointer from that, so it's no use here.
So the only way I've managed to get this to work is by using a preprocessor macro:
#define convert(f) [](double x, void*) { return f(x); }
This then lets me write something like this:
#include <iostream>
using namespace std;
typedef double gsl_function_type(double, void*); // convenient typedef
// example GSL function call
double some_gsl_function(gsl_function_type* function)
{
return function(5.0, nullptr);
}
// function we want to pass to GSL
double a_squared(double a) { return a*a; }
// macro to define an inline lambda wrapping f(double) in GSL signature
#define convert(f) [](double x, void*) { return f(x); }
int main()
{
cout << some_gsl_function(convert(a_squared)) << endl;
}
Personally, as much as I dislike using macros, I would prefer this over my other suggestion. In particular, it solves the problems @Walter pointed out with that idea.