lambda函数与gsl的数值积分
Numerical integration of lambda function with gsl
我正在使用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>'
@user657267给出的答案是正确的。这就是为什么需要一个小包装器来将带有捕获的lambda转换为gsl_function。
这是f gsl_function的包装器,这是fdf gsl_function的包装器
使用这两个答案中提出的包装器后,您可以通过以下方式将lambda函数转换为gsl_function(我还没有发明带有std::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);
只有没有捕获的lambda才能转换为函数指针。
[expr.prim.lambda]
6具有no的非泛型lambda表达式的闭包类型lambda捕获具有公共非虚拟非显式常量转换函数到指向函数的指针,带有C++语言链接(7.5)与闭包类型的函数相同的参数和返回类型呼叫接线员。
本质上,这意味着
[] (double, void*) {return 2.0;};
就好像它被定义为
class Lambda
{
public:
double operator()(double, void*);
operator double(*)(double, void*)() const;
};
如果lambda有一个捕获,但是没有定义转换函数,并且lambda不能转换为常规函数指针。
相关文章:
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 将gsl c++程序与"英特尔MKL"链接
- 如何在 SCIP C++ 接口中获取 MILP 约束矩阵中的系数值
- 在C++中返回不正确的楼层函数值
- 如何从文本文件中读取数值,直到遇到字符类型?
- C++ 警告:将新创建的 gsl::owner<> 分配给非所有者
- 基于字节数组生成静态范围整数值
- 如何在逗号后使用 cout 打印整数值,而无需在逗号后添加额外的零C++?
- 如何为静态常量模板化专用整数值分配存储
- 测试整数值以确定它是奇数还是偶数C++
- 没有额外参数的函数的 GSL 数值积分
- 传递通用函数,用于梯形规则的数值积分
- gsl多变量数值积分
- 计算C 中的数值积分
- 数值积分:使模板函数只接受函数名或使用两个参数调用的函数
- lambda函数与gsl的数值积分
- 物理引擎的数值积分有哪些好算法
- 用c++在给定网格上进行数值积分,离散化为固定常数
- 梯形规则的数值积分c++
- 如何在R中使用Rcpp在c++中做数值积分