Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ lambda函数与gsl的数值积分_C++_Lambda_Gsl_Numerical Integration - Fatal编程技术网

C++ lambda函数与gsl的数值积分

C++ lambda函数与gsl的数值积分,c++,lambda,gsl,numerical-integration,C++,Lambda,Gsl,Numerical Integration,我正在与gsl合作集成一个功能。该函数内置于lambda函数中,该函数的输入为double,输出为void*。 现在,如果我使用lambda而不使用任何变量捕获,那么一切都很好。但是如果我做变量捕获,它就不再工作了 谁能解释一下为什么会这样 下面是我为解释我的问题而编写的两段代码: 这个很好用: int main(int argc, char **argv) { double beg = 0; double end = 10; auto f = [] (double

我正在与gsl合作集成一个功能。该函数内置于lambda函数中,该函数的输入为double,输出为void*。 现在,如果我使用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;

}
出现以下错误:

Assigning to 'double (*)(double, void *)' from incompatible type '<lambda at /[omissis]/main.cpp>'
从不兼容类型“”分配给“double(*)(double,void*)”

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

[expr.prim.lambda]

6非泛型lambda表达式的闭包类型为no lambda capture具有公共非虚拟非显式常量转换 具有C++语言链接(7.5)的函数指向函数< /强>的指针 与闭包类型的函数相同的参数和返回类型 呼叫接线员

本质上这意味着

[] (double, void*) {return 2.0;};
就好像它被定义为

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

如果lambda有捕获,但转换函数未定义,且lambda无法转换为常规函数指针。

由@user657267给出的答案是正确的。这就是为什么需要一个小包装器来将带有capture的lambas转换为gsl_函数

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

//std::函数版本
双a=1;
gsl_函数_pp Fp([=](double x)->double{return a*x;});
gsl_函数*F=静态_转换(&Fp);
//模板版本
双a=1;
自动ptr=[=](双x)->double{returna*x;};
gsl_功能_pp Fp(ptr);
gsl_函数*F=静态_转换(&Fp);

这正是我想要的!如果您愿意,您可以对其他答案进行投票:)std::function在哪里?lambda函数已转换为std::function
[] (double, void*) {return 2.0;};
class Lambda
{
public:
  double operator()(double, void*);
  operator double(*)(double, void*)() const;
};
// 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);