This question already has answers here:
Function pointer to member function
(8 answers)
Closed 5 years ago.
I would like to integrate a function with gsl. Therefor I have to define a function f (the integrant, which has to be of the form double (*)(double, void*)). For the call of the gsl integration method I need to define a struct, which contains a pointer to a function (this struct is called gsl_function).
gsl_function F;
F.function = &MyClass::my_f;
The function f must be implemented in a class (in the same class from which the integration procedure should be called). How can I assign the pointer above correctly, since the 2nd line is not compiling and leads to the error:
cannot convert ‘double (MyClass::*)(double, void*)’ to ‘double (*)(double, void*)’ in assignment.
Here the definition of my_f
struct my_f_params { double a; double b;};
double my_f (double x, void * p) {
struct my_f_params * params = (struct my_f_params *)p;
double a = (params->a);
double b = (params->b);
return 1.0/(sqrt(a * (1.0 + x)*(1.0 + x)*(1.0 + x) + (1-a) * std::pow((1.0 + x), (3.0 * (1.0 + b)))));
}
which has to be of the form double (*)(double, void*)
Non static member function declarations involve the implicit call scope qualifier as stated in the error message
double (MyClass::*)(double, void*)
// ^^^^^^^^^
This is different from the callback function pointer definition.
What you probably can do with such interface, is to pass the this pointer through the void* argument of the callback function:
class MyClass {
static double func(double d,void* thisPtr) {
MyClass* myClass = (MyClass*)thisPtr;
// do something
}
};
As mentioned in the documentation you can set the params like that in a wrapper class:
class gsl_function_wrapper {
public:
gsl_function_wrapper() {
F.function = &func;
F.params = this;
}
private:
gsl_function F;
double a;
double b;
static double func(double d,void* thisPtr) {
gsl_function_wrapper* myWrapper = (gsl_function_wrapper*)thisPtr;
// do something with a and b
foo(d,myWrapper->a,myWrapper->b);
}
};
Related
I am working with gsl to integrate a function. That function is built in a lambda function that has as input a double and a void *, and as output a double.
Now, everything works fine if I use the lambda without any variable capture. But if I do variable capturing, it doesn't work any more.
Could anyone explain me why so?
Here are two snippets of code that I made up to explain my problem:
This one works fine:
int main(int argc, char **argv)
{
double beg = 0;
double end = 10;
auto f = [] (double x, void * p) {return 2.0;};
gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_INTEGRATION_WORKSPACE_SIZE);
double result;
double error;
gsl_function F;
F.function = f;
F.params = NULL;
gsl_integration_qags (&F, beg, end, 0, GSL_INTEGRATION_RELATIVE_PRECISION, GSL_INTEGRATION_WORKSPACE_SIZE, w, &result, &error);
cout<<result<<endl;
}
While this one
int main(int argc, char **argv)
{
double beg = 0;
double end = 10;
double p = 2.0;
auto f = [&] (double x, void * p) {return p;};
gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_INTEGRATION_WORKSPACE_SIZE);
double result;
double error;
gsl_function F;
F.function = f;
F.params = NULL;
gsl_integration_qags (&F, beg, end, 0, GSL_INTEGRATION_RELATIVE_PRECISION, GSL_INTEGRATION_WORKSPACE_SIZE, w, &result, &error);
cout<<result<<endl;
}
Yields on the line
F.function = f;
the following error:
Assigning to 'double (*)(double, void *)' from incompatible type '<lambda at /[omissis]/main.cpp>'
The answer given by #user657267 is correct. That is why a small wrapper is needed to convert lambas with capture to gsl_function.
Here is the wrapper for the f gsl_function and Here is the wrapper for the fdf gsl_function
You can convert lambda functions to gsl_function after using the wrapper proposed in these two answers in the following way (I haven't invented the version with std::function, it was a well known answer. The template version I haven't seen before my answer).
// std::function version
double a = 1;
gsl_function_pp Fp([=](double x)->double{return a*x;});
gsl_function *F = static_cast<gsl_function*>(&Fp);
//template version
double a = 1;
auto ptr = [=](double x)->double{return a*x;};
gsl_function_pp<decltype(ptr)> Fp(ptr);
gsl_function *F = static_cast<gsl_function*>(&Fp);
Only lambdas without captures can be converted to function pointers.
[expr.prim.lambda]
6 The closure type for a non-generic lambda-expression with no
lambda-capture has a public non-virtual non explicit const conversion
function to pointer to function with C++ language linkage (7.5) having
the same parameter and return types as the closure type’s function
call operator.
Essentially what this means is that
[] (double, void*) {return 2.0;};
acts as though it were defined as
class Lambda
{
public:
double operator()(double, void*);
operator double(*)(double, void*)() const;
};
if the lambda has a capture however the conversion function is not defined, and the lambda cannot be converted to a regular function pointer.
This question already has answers here:
C++ function pointer (class member) to non-static member function
(6 answers)
Closed 10 years ago.
I'm trying to make a code that find the numerical derivation of a function.
I also have a polynomial class described as follows:
class polynomial
{
public:
polynomial(Vector, int);
polynomial();
~polynomial();
double returnValue(double);
void print();
private:
int Degree;
Vector Coeficients;
};
my numerical derivation have the following prototype:
double numericalDerivation( double (*F) (double), double x);
I want to pass the returnValue method into the numericalDerivation, is that possible?
Yes, it is possible, but don't forget it is a member function: you won't be able to call it without having a (pointer to) an object of type polynomial on which to invoke it.
Here is how the signature of your function should look like:
double numericalDerivation(double (polynomial::*F)(double), polynomial* p, double x)
{
...
(p->*F)(x);
...
}
Here is how you would invoke it:
double d = ...;
polynomial p;
numericalDerivation(&polynomial::returnValue, &p, d);
Alternatively, you could use an std::function<> object as a parameter of your function, and let std::bind() take care of binding the object to the member function:
#include <functional>
double numericalDerivation(std::function<double(double)> f, double x)
{
...
f(x);
...
}
...
double d = ...;
polynomial p;
numericalDerivation(std::bind(&polynomial::returnValue, p, std::placeholders::_1), d);
Can you please explain what does the following line means?
typedef int (*Callback)(void * const param,int s)
It means that Callback is a new name for the type : pointer to a function returning an int and taking two parameters of type 'const pointer to void' and 'int'.
Given a function f :
int f(void * const param, int s)
{
/* ... */
}
The Callback can be used to store a pointer to f :
Callback c = &f;
The function f can be later invoked through the pointer without directly referring to its name :
int result = c(NULL, 0);
At the point of the call, the name f does not appear.
It creates a new "alias" or name by which you can refer to pointers to functions that return int and take two parameters: a void* const and an int. You can then create variables of that type, assign to them, invoke the function through them etc as in:
int fn(void * const param,int s) { ... }
Callback p;
p = fn;
int x = p(NULL, 38);
Note that typedefs do not really create new types... every equivalent typedef is resolved to the single real type for the purposes of overload resolution, template instantiation etc..
It declares a function type:
// Set up Callback as a type that represents a function pointer
typedef int (*Callback)(void * const param,int s);
// A function that matches the Callback type
int myFunction(void* const param,int s)
{
// STUFF
return 1;
}
int main()
{
// declare a variable and assign to it.
Callback funcPtr = &myFunction;
}
i can't understand following defining pointer variable. can you help me?
double(*)(double *) foo;
note : sory, i edit name of variable func to foo.
This is not valid C. Perhaps you mean this:
double(*func)(double *);
which declares func as a pointer to a function that takes a pointer-to-double, and returns a double.
You can use http://cdecl.org for this sort of thing.
Try this (tested):
// functions that take double * and return double
double dfunc(double *d) { return (*d) * 2.0; }
double tfunc(double *d) { return (*d) * 3.0; }
int main()
{
double val = 3.0;
double // 3. the function returns double
(*pFunc) // 1. it's a pointer to a function
(double *); // 2. the function takes double *
pFunc = dfunc;
printf("%f\n", pFunc(&val)); // calls dfunc()
pFunc = tfunc;
printf("%f\n", pFunc(&val)); // calls tfunc()
}
Output:
6.000000
9.000000
it's a pointer to a function returning double having a parameter of type pointer to double, if you correct the variable declaration since as it stands its just incorrect correct syntax would be double (*foo) (double*)
uses are polymorphism by being able to replace a function:
struct memory_manager{
void*(*getmem)(size_t);
void(*freemem)(void*);
}mem_man;
void* always_fail(size_t){return 0;}
void* myalloc(size_t s){
void* p=mem_man.get_mem(s);
if(p) return p;
mem_man.getmem=always_fail;
return 0;
}
void myfree(void* p){
if(p) freemem(p);
}
it's not really the c++-way i geuss, since for most purposes inheritance and virtual functions offer a better solution, but if you're restricted to c, then you can use this technique to simulate virtual functions.
Is there a way in C++ to effectively create a closure which will be a function pointer? I am using the Gnu Scientific Library and I have to create a gsl_function. This function needs to effectively "close" a couple of parameters available when I create it. Is there a nice trick to create a closure so that I don't have to pass all of them as params in the gsl_function structure? If not, should I just pass in a pointer to an array containing these parameters?
EDIT
I have tried to use boost::bind like this:
#include <gsl/gsl_integration.h>
#include <boost/bind.hpp>
#include "bondpricecalculator.h"
#include "functions.h"
double integrand (double xi, double t, double x, void * p) {
Functions *functions = (Functions *) p;
double vx = functions->v(x);
return functions->rho0(x)*exp(vx * xi - 0.5 * vx * vx * t);
}
double BondPriceCalculator::value(double t, double T, double xi)
{
gsl_integration_workspace * w
= gsl_integration_workspace_alloc (10000);
gsl_function F;
F.function = &boost::bind(integrand, xi, t, _1, _2);
F.params = &functions;
double integral_t;
double integral_T;
double error;
int res = gsl_integration_qags(&F, T, 1e+14, 0, 1e-7, 10000, w, &integral_T, &error);
if(res)
{
throw "Error intgrating";
}
int res = gsl_integration_qags(&F, T, 1e+14, 0, 1e-7, 10000, w, &integral_t, &error);
if(res)
{
throw "Error intgrating";
}
return integral_T/integral_t;
}
but I got the following error message:
/home/ga/svn/PhD/inflation/cpp/ioi/bondpricecalculator.cpp:20: error: cannot convert ‘boost::_bi::bind_t<double, double (*)(double, double, double, void*), boost::_bi::list4<boost::_bi::value<double>, boost::_bi::value<double>, boost::arg<1>, boost::arg<2> > >*’ to ‘double (*)(double, void*)’ in assignment
I found below code at.
http://bytes.com/topic/c/answers/657124-interface-problem
// Use in combination with boost::bind.
template<class F>
static double gslFunctionAdapter( double x, void* p)
{
// Here I do recover the "right" pointer, safer to use static_cast
// than reinterpret_cast.
F* function = static_cast<F*>( p );
return (*function)( x );
}
template<class F>
gsl_function convertToGslFunction( const F& f )
{
gsl_function gslFunction;
const void* p = &f;
assert (p != 0);
gslFunction.function = &gslFunctionAdapter<F>;
// Just to eliminate the const.
gslFunction.params = const_cast<void*>( p );
return gslFunction;
}
and use this like
gslFunction gslF = convertToGslFunction( boost::bind( &Sde::drift, &sde, _1 ) );
Take a look at this simple example of combining boost::bind and boost::function.
I'm guessing from all those "gsl_" prefixes that the library is not C++, but plain C. Which means it doesn't grok C++ closures (functors). You can't pass a C++ functor to a C function. You'll have to pass void pointers around, cross your fingers and reinterpret_cast them into C oblivion.
Though bradgonesurfing has given a nice answer that will work for converting closures into gsl_functions without any further thought, I would like to share with you the idiom for doing a direct translation from C++ into C.
Supposing you have the closure:
double a;
[&a](double x){return a+x;}
You would convert translate this into an equivalent function pointer idiom as follows:
struct paramsAPlusX{
double* a;
paramsAPlusX(double & a_):a(&a_){}
}
double funcAPlusX(double x, void* params){
paramsAPlusX* p= (paramsAPlusX*)params;
return *(p->a) + x;
}
//calling code:
double a;
paramsAPlusX params(a);
gsl_function f;
f.function=funcAPlusX;
f.params=¶msAPlusX;
//use f here.
Many C libraries use this sort of idiom, and they don't all use a struct for it (they frequently pass it as two separate parameters to the function) so automatic conversion isn't always possible.