假设我想在pthreads上实现一个简单的抽象。 (或任何带有回调或线程函数指针的C API)。
与std :: thread一样,我希望接口能够通常使用函数对象。
如何以适用于所有情况的方式弥合差距? (包括绑定,lambda函数等)
我知道std :: function :: target但afaik,它没有做我需要的。
答案 0 :(得分:0)
如果API为用户数据采用void*
的函数,例如pthread_create()
,则将指向该函数的指针作为用户数据传递,调用一个转换用户数据的蹦床到您的函数类型,并调用该函数。例如:
#include <functional>
#include <pthread.h>
extern "C" void* trampoline(void* userData) {
return (*static_cast<std::function<void*()>*>(userData))();
}
void* start() {
// ...
return 0;
}
int main() {
pthread_t thread;
std::function<void*()> entry(start);
pthread_create(&thread, 0, &trampoline, &entry);
// ...
}
然而,直接的暗示是功能对象的生命周期不容易控制。在上面的例子中,std::function<void*()>
对象碰巧活得足够长,但并不总是那么容易。
如果您尝试调用的函数没有用户数据参数,那么您几乎没有运气。你可能会使用全局对象,但这几乎肯定是一种相当脆弱的方法。
答案 1 :(得分:0)
lambda函数可以在任何需要常规函数指针的地方使用。换句话说,它可以在任何使用常规函数/函数指针的地方使用..
#include <iostream>
void voidfunc(void (*func_ptr)(void))
{
func_ptr();
}
void funcwithargs(void (*func_ptr)(int, char, std::string), int a, char b, std::string c)
{
func_ptr(a, b, c);
}
int main()
{
auto vf = []{std::cout<<"Called void func..\n";};
auto vfwa = [](int a, char b, std::string c) {std::cout<<"Called func with args with: "<<a<<b<<" "<<c<<"\n";};
voidfunc(vf);
funcwithargs(vfwa, 10, 'x', " + 3");
return 0;
}
同样,您可以使用std::function
代替函数指针..