所以我正在尝试编写一个与c ++ 11 lambdas一起使用的Integration函数.代码看起来像这样:
double Integrate(std::function<double(double,void*)> func, double a,double b,std::vector<double> & params)
{
gsl_integration_workspace * w = gsl_integration_workspace_alloc (1000);
gsl_function F;
F.function =func;
F.params = (void*)¶ms;
double error,result;
gsl_integration_qag (&F, a, b, 0, 1e-7, 1000,GSL_INTEG_GAUSS61,w, &result, &error);
gsl_integration_workspace_free (w);
return result;
}
void Another_function()
{
//...
Integrate([](double a,void* param)
{
return ((vector<double> *)params)->at(0)*a+((vector<double> *)params)->at(1);
}
,0,3,{2,3});
}
Run Code Online (Sandbox Code Playgroud)
试图编译它,编译器说:
error: cannot convert ‘std::function<double(double, void*)>’ to ‘double (*)(double, void*)’ in assignment
Run Code Online (Sandbox Code Playgroud)
关于线
F.function =func;
Run Code Online (Sandbox Code Playgroud)
但如果我写:
F.function =[](double a,void* param)
{
return ((std::vector<double> *)param)->at(0)*a+((std::vector<double> *)param)->at(1);
};
Run Code Online (Sandbox Code Playgroud)
它编译并正常工作.我该怎么解决这个问题?
使用 void* 是典型的 C 回调接口,用于将某些“状态”传递给函数。然而, std::function 不需要这个,因为 std::function 支持“有状态函数”。所以,你可以这样做:
double Integrate(
std::function<double(double)> func,
double a, double b)
{
typedef std::function<double(double)> fun_type;
:::
F.function = [](double x, void* p){
return (*static_cast<fun_type*>(p))(x);
};
F.params = &func;
:::
}
Run Code Online (Sandbox Code Playgroud)
并将参数向量的引用存储为函子的一部分,该函子将封装在 std::function 对象中,或者执行如下操作:
void Another_function()
{
double m = 2;
double b = 3;
auto func = [&](double x){return m*x+b};
auto r1 = Integrate(func,0,3);
:::
}
Run Code Online (Sandbox Code Playgroud)
然而,该解决方案将使用相当多的间接方法。GSL 将调用您的 lambda。您的 lambda 会调用 std::function<>::operator() ,而 std::function<>::operator() 又会调用某种用于类型擦除的虚函数,而类型擦除又会调用实际的计算。
因此,如果您关心性能,则可以删除其中的几层,特别是 std::function。这是使用函数模板的另一种方法:
template<class Func>
double Integrate(
Func func,
double a, double b)
{
:::
F.function = [](double x, void* p)->double{
return (*static_cast<Func*>(p))(x);
};
F.params = &func;
:::
}
Run Code Online (Sandbox Code Playgroud)
我想我更喜欢这个而不是 std::function 解决方案。
| 归档时间: |
|
| 查看次数: |
2276 次 |
| 最近记录: |