lambda函数与gsl的数值积分

时间:2014-10-29 08:58:42

标签: c++ lambda gsl numerical-integration

我正在使用gsl来集成一个函数。该函数构建在lambda函数中,该函数具有double和void *作为输入,并且输出为double。 现在,如果我使用没有任何变量捕获的lambda,一切正常。但如果我做变量捕获,它就不再起作用了。

有人可以解释我为什么这样吗?

以下是我用来解释我的问题的两段代码:

这个很好用:

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;

}

虽然这个

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;

}

生产线

F.function = f;

以下错误:

Assigning to 'double (*)(double, void *)' from incompatible type '<lambda at /[omissis]/main.cpp>'

2 个答案:

答案 0 :(得分:3)

@ user657267给出的答案是正确的。这就是为什么需要一个小包装器来将带有捕获的lambas转换为gsl_function。

Here is the wrapper for the f gsl_functionHere is the wrapper for the fdf gsl_function

在使用这两个答案中提出的包装器之后,您可以将lambda函数转换为gsl_function(我没有用std :: function发明版本,这是一个众所周知的答案。模板版本I在我的回答之前没见过)。

// 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); 

答案 1 :(得分:2)

只有没有捕获的lambda才能转换为函数指针。

[expr.prim.lambda]

  

6具有 no的非泛型lambda表达式的闭包类型   lambda-capture 具有公共非虚拟非显式const 转换   函数指向函数与C ++语言链接(7.5)有   与闭包类型的函数相同的参数和返回类型   呼叫运营商。

基本上这意味着

[] (double, void*) {return 2.0;};

就像定义为

一样
class Lambda
{
public:
  double operator()(double, void*);
  operator double(*)(double, void*)() const;
};

如果lambda有捕获但是没有定义转换函数,并且lambda不能转换为常规函数指针。