通过引用传递函数的问题与打字

Passing function by reference problem with typing

我正在尝试使用 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 替换为 Integrand1 和 [= 时,所有这些都有效19=]。我怎样才能让编译器相信 func 是一个具有正确原型的函数?

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

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