如何从lambda表达式中获取函数指针?

时间:2017-07-28 03:26:45

标签: c++ c++11 lambda

我要调用C语言函数:

f_api(void(*callback)(int))

我有一个回调的静态类方法:

struct A {
    static void CallBack(int i) {
        A::count = i;
    }
    static count = 0;
};

我可以这样调用函数:

f_api(&A::CallBack)

但是,我现在必须将回调更改为非静态,因为我必须创建多个A对象。

但我不能改变f_api()的定义。

我尝试使用lambda:

f_api([this](int i)->void{this->count = i;})`

但这失败了,因为我无法将带有捕获的lambda转换为简单的函数指针。

由于std::bind()定义,

f_api()也无法完成工作。

我能为此做些什么?如何从lambda表达式中获取函数指针?有什么方法可以回避吗?

2 个答案:

答案 0 :(得分:3)

如果您无法更改C API,那么我不认为您可以对此情况做很多事情。因为C函数需要将所需的所有信息作为函数参数传递。

您可以使用以下

将lambda转换为函数指针
void (*ptr) () = []() {}

没有任何捕获的Lambda可以隐式转换为函数指针。但是捕获值的lambda无法转换为函数指针,因为它们具有额外的状态(以成员变量的形式)。

在C中解决此问题的常用方法是使用void*参数。看一下pthread_create函数。线程启动函数接受一个带有void*参数的函数,该函数指向" context"。在您的情况下,此上下文可能类似于您调用方法的实例。

但是如果你不能改变C API,那么恐怕你对函数指针做不了多少。您唯一能做的就是使变量全局化,然后使用它们在函数指针中调用这些方法。

答案 1 :(得分:0)

以下是我的想法: 也许我不能通过从lambda获取函数指针来做到这一点。但是我做了一些其他的滴答来得到多个As来回避这个问题......

template<unsigned int ClassCount>
struct A {
    static void CallBack(int i) {
        A::count = i;
    }
    static int count;
};

template<unsigned int ClassCount>
int A<ClassCount>::count = 0;

所以我可以:

f_api(&A<0>::CallBack);
std::cout << A<0>::count << std::endl;
f_api(&A<1>::CallBack);
std::cout << A<1>::count << std::endl; // A<0>::count is different from A<1>::count
在某些情况下,这可能是一个潜在的解决方案,但遗憾的是,不是在矿井中。