通过引用传递函数的问题

问题描述 投票:1回答:1

我正在尝试用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是具有正确原型的函数?

c++ gsl
1个回答
0
投票

编译器为您提供答案:您需要一个函数指针类型来代替double&

void EvalIntegral(double (*func)(double*, std::size_t, void*), ...)
© www.soinside.com 2019 - 2024. All rights reserved.