2014-10-29 104 views
2

我正在使用gsl来集成一个函数。该函数构建在一个lambda函数中,该函数具有double和void *作为输入,并且输出double。 现在,如果我使用没有任何变量捕获的lambda表达式,一切正常。但是如果我进行可变捕获,它就不再工作了。lambda函数与gsl的数值积分

任何人都可以解释我为什么这样吗?

这里有两个代码片段是我做了解释我的问题:

这一个正常工作:

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>' 

回答

3

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

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

您可以将lambda函数使用下列方式这两个答案提出的包装(我没有发明了的std ::功能的版本后gsl_function,这是一个众所周知的答案。我的答案之前我没有见过的模板版本)。

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

这正是我一直在寻找的! – 2014-10-30 07:51:41

+0

如果你喜欢,你可以给其他答案:) – 2014-10-30 15:52:34

+0

哪里是'std :: function'? – Walter 2015-09-27 17:29:17

2

只有没有捕获的lambda可以转换为函数指针。

[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.

本质上这是什么意思是

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

行为好象它被定义为

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

如果拉姆达具有但是捕获的转换函数没有定义,并且lambda不能转换为常规的函数指针之三。