I was playing with C++ lambdas and their implicit conversion to function pointers. My starting example was using them as callback for the ftw function. This works as expecte
ORIGINAL
Lambda functions are very convenient and reduce a code. In my case I needed lambdas for parallel programming. But it requires capturing and function pointers. My solution is here. But be careful with scope of variables which you captured.
template
Tret lambda_ptr_exec(T* v) {
return (Tret) (*v)();
}
template
Tfp lambda_ptr(T& v) {
return (Tfp) lambda_ptr_exec;
}
Example
int a = 100;
auto b = [&]() { a += 1;};
void (*fp)(void*) = lambda_ptr(b);
fp(&b);
Example with a return value
int a = 100;
auto b = [&]() {return a;};
int (*fp)(void*) = lambda_ptr(b);
fp(&b);
UPDATE
Improved version
It was a while since first post about C++ lambda with captures as a function pointer was posted. As It was usable for me and other people I made some improvement.
Standard function C pointer api uses void fn(void* data) convention. By default this convention is used and lambda should be declared with a void* argument.
Improved implementation
struct Lambda {
template
static Tret lambda_ptr_exec(void* data) {
return (Tret) (*(T*)fn())(data);
}
template
static Tfp ptr(T& t) {
fn(&t);
return (Tfp) lambda_ptr_exec;
}
template
static void* fn(void* new_fn = nullptr) {
static void* fn;
if (new_fn != nullptr)
fn = new_fn;
return fn;
}
};
Exapmle
int a = 100;
auto b = [&](void*) {return ++a;};
Converting lambda with captures to a C pointer
void (*f1)(void*) = Lambda::ptr(b);
f1(nullptr);
printf("%d\n", a); // 101
Can be used this way as well
auto f2 = Lambda::ptr(b);
f2(nullptr);
printf("%d\n", a); // 102
In case return value should be used
int (*f3)(void*) = Lambda::ptr(b);
printf("%d\n", f3(nullptr)); // 103
And in case data is used
auto b2 = [&](void* data) {return *(int*)(data) + a;};
int (*f4)(void*) = Lambda::ptr(b2);
int data = 5;
printf("%d\n", f4(&data)); // 108