C函数指针与C ++ 11 lambdas [英] C function pointers with C++11 lambdas

查看:125
本文介绍了C函数指针与C ++ 11 lambdas的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图写一个Integration函数与c ++ 11 lambdas一起使用。代码看起来像这样:

So i'm trying to write an Integration function to be used with c++11 lambdas. The code looks something like this:

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*)&params;
  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});
}

尝试编译这个,编译器说:

Trying to compile this, compiler says:

error: cannot convert ‘std::function<double(double, void*)>’ to ‘double (*)(double, void*)’ in assignment



$ b

about line

F.function =func;

但如果我写:

F.function =[](double a,void* param)
   {
   return ((std::vector<double> *)param)->at(0)*a+((std::vector<double> *)param)->at(1);
   };

它编译和工作正常。我应该如何解决这个问题?

It compiles and works fine. How should I solve this?

推荐答案

使用void *是典型的C回调接口向函数传递一些状态。但是,std :: function不需要这个,因为std :: function支持有状态的函数。因此,您可以执行这样的操作:

Using a void* is typical of C callback interfaces to pass some "state" to the function. However, std::function does not need this because std::function supports "stateful functions". So, you could do something like this:

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;
    :::
}

并存储对参数向量的引用部分函数将被封装在std :: function对象中,或者做这样的事情:

and store a reference to the parameter vector as part of the functor that will be encapsulated in the std::function object or do something like this:

void Another_function()
{
    double m = 2;
    double b = 3;
    auto func = [&](double x){return m*x+b};
    auto r1 = Integrate(func,0,3);
    :::
}

然而,这个解决方案会使用许多不确定。 GSL将调用您的lambda。你的lambda将调用std :: function<> :: operator(),它反过来会唤醒某种虚拟函数,用于类型擦除,反过来调用实际的计算。

However, this solution would use rather many indirections. GSL would invoke your lambda. Your lambda would invoke the std::function<>::operator() which in turn would inwoke some kind of virtual function that is used for type erasure which would in turn invoke the actual computation.

所以,如果你关心性能,你可以去掉一些层,特别是std :: function。这里是另一种具有函数模板的方法:

So, if you care about performance, you could get rid of a couple of layers there, specifically std::function. Here's a another approach with a function template:

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;
    :::
}

我想我更喜欢这个std :: function solution。

I guess I would prefer this over the std::function solution.

这篇关于C函数指针与C ++ 11 lambdas的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆