通过键入的引用问题传递函数

Passing function by reference problem with typing

本文关键字:引用 问题 传递函数      更新时间:2023-10-16

我正在尝试用GSL从数字上计算一些棘手的积分,我希望实现将积分与GSL实现分开,以使我的代码更具可读性(和可调试性(。这些是实际评估我的模型的函数,其中的内容并不重要:

double Integrand1(double *k, size_t dim, void *params) {
double result = k[0]*k[1]*k[2];
return result;
}      
double Integrand2(double *k, size_t dim, void *params) {
double result = k[0]-k[1]-k[2];
return result;
}      

这就是我遇到麻烦的地方,试图抽象对 GSL 的调用。请注意gsl_monte_function G的类型约束:

void EvalIntegral(double &func, int_info &params,double *xl,double *xu,size_t dim,
double &result,double &error){
const gsl_rng_type *T;
gsl_rng *r;
gsl_monte_function G;
G.f = &func;  //This must be double (*)(double *,size_t,void *)
G.dim = dim;  //This must be size_t
G.params = &params; //This is a struct holding some variables
size_t calls = 5e5;
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc(T);
gsl_monte_vegas_state *s = gsl_monte_vegas_alloc(dim);
gsl_monte_vegas_integrate(&G,xl,xu,dim,1e5,r,s, &result,&error);
gsl_monte_vegas_free (s);
gsl_rng_free (r);  
}

我设置了上述函数以减少另一个函数中的一些混乱:

void Evaluate(double x, double y){
int_info params;
params.x = x; 
params.y = y;
//Lower limits to the variables 
double xl[3] = {0.,-100.,0.};
//Upper limits to the variables
double xu[3] = {100.,100.,1.};
double result1, result2, error1, error2;
EvalIntegral(&Integrand1,&params,xl,xu,3,&result1,&error1);
EvalIntegral(&Integrand2,&params,xl,xu,3,&result2,&error2);
}

但是,当我编译时,它似乎拒绝我传递积分函数:

error: cannot convert ‘double*’ to ‘double (*)(double*, size_t, void*)’ {aka ‘double (*)(double*, long unsigned int, void*)’} in assignment
G.f = &func;
^~~~

我有点困惑,当我将EvalIntegral的内容复制到Evaluate两次并将func替换为Integrand1Integrand2时,所有这些都有效。如何说服编译器func是一个具有正确原型的函数?

编译器会给出答案: 而不是double&你需要一个函数指针类型:

void EvalIntegral(double (*func)(double*, std::size_t, void*), ...)