C ++如何获取指向lambda函数的void指针?

时间:2015-12-16 01:38:27

标签: c++ function pointers lambda

我甚至无法输入示例代码......很丢失。这是我的原始函数,它不是lambda函数(我希望它是lambda)。

static void* DoublePointer(void** arg, int arg_sz) {
    double* n1 = In(arg[0]);
    double* n2 = In(arg[1]);
    double* n3 = In(arg[arg_sz-1]);

    *n3 = *n1 + *n2;

    return n3;
}

void* func_ptr = DoublePointr; //works fine

但我真正想要的是:

my_class.save_the_func = [](void** arg, int arg_sz) {
    double* n1 = In(arg[0]);
    double* n2 = In(arg[1]);
    double* n3 = In(arg[arg_sz-1]);

    *n3 = *n1 + *n2;

    return n3;
}

my_class.point_to_func = save_the_func // point_to_func is the void* member

你最后得到一个指向lambda函数的void *你需要做什么?就像我说的,非lambda函数工作正常。

我之所以这么想是因为最终我希望我的代码看起来像这样:

std::vector<function_entry> MyFuncEntry ={
add_function("MRP_DoublePointer2", "double", "double,double", "n1,n2", "add two numbers",
    [](void** arg, int arg_sz)->void* {
    double* n1 = In(arg[0]);
    double* n2 = In(arg[1]);
    double* n3 = In(arg[arg_sz-1]);

    *n3 = *n1 + *n2;

    return n3;
}),

add_function("MRP_DoublePointer3", "double", "double,double", "n1,n2", "add two numbers",
    [](void** arg, int arg_sz)->void* {
    double* n1 = In(arg[0]);
    double* n2 = In(arg[1]);
    double* n3 = In(arg[arg_sz-1]);

    *n3 = *n1 + *n2;

    return n3;
})

};

换句话说,我想在同一个地方定义一个函数和一些其他所需的参数。 Add_function返回一个function_entry类,它包含一些字符串和lambda函数,基本上我正在尝试在函数旁边定义那些字符串,这样它更容易维护,它不在两个不同的地方。

如果这是坏的/计算上昂贵的话,我想我应该坚持使用非lambda。

这是我得到的错误: lambda error

3 个答案:

答案 0 :(得分:1)

获取lambda表达式的void*指针的问题在于lambda表达式的结果是一个真实的诚实对象,而不是指向对象的指针。就像您无法将std::vectorstd::string分配给void*一样,您无法将lambda表达式的结果分配给void*

有趣的是,您编写的初始代码 - 将函数指针指定给void* - 实际上并不能保证编译! C ++标准区分了函数指针和对象指针,并且它们在两者之间不可移植。实际上,有些编译器会完全拒绝你的代码。

如果您需要存储指向任意函数类型的指针,请考虑使用std::function,这是类型安全的,并且更清楚地表明您正在尝试做什么。

答案 1 :(得分:1)

您尝试做的只会在某些情况下起作用;最后看到警告。 Lambda不是函数,你不能为它们获取函数指针地址。但是,你可以做的是同时创建一个函数和一个协同工作的lambda。

std::function f;
void call_f()
{
    f();
}

只需分配到f并将call_f的地址传递给您的API。

大警告:这甚至不像编写的那样远程线程安全。如果您在多处理环境中需要,请将其保护为任何其他一次性使用的资源。如果只有一个是热点太多,你可以制作一个固定大小的函数池,但这要复杂得多。

答案 2 :(得分:0)

格式声明C风格labmda函数的类型名称

return_type ( * ) ( params )

就我们而言,就是这样:

using my_lambda_type = void*(*)(void**, int)

现在我们宣布:

my_lambda_type my_func = [](void** args, int arg_sz)->void* { /*do stuff*/ }

您可以省略->void*以自动推断返回类型。

最后:

void* my_func_pointer = my_func;

奖励,这里是如何将c风格的lambda定义为函数参数输入

void func_with_func_parameter(void*(*par_name_goes_here)(void**, int)) 
{
    //do stuff
}

与:

相同
void func_with_func_parameter(my_lambda_type param_name_goes_here) 
{
    //do stuff
}