不捕获任何内容的C ++ 11 lambda可以存储在函数指针中。只需要确保lambda接受并返回与函数指针相同的参数。
在GObject库中,所有回调的类型都为void(*GCallback) (void)
。但是,这个定义不会影响回调的签名:
用于结构定义和中的回调函数的类型 功能签名。这并不意味着所有回调函数 必须没有参数并返回void。所需的签名 回调函数由使用的上下文确定(例如, 它所连接的信号)。使用G_CALLBACK()来强制转换 回调函数到GCallback。
换句话说,可以传递这样的函数:
int my_function(int a, char b) {}
通过强制转换它的类型(这就是G_CALLBACK所做的):
do_something(G_CALLBACK(my_function));
不幸的是,类型转换不适用于C ++ 11 lambdas:
do_something(G_CALLBACK([](int a, char b) -> int {...});
// Cannot cast from type lambda to pointer type GCallback
是否可以使用任意类型的C ++ lambdas代替GCallback?
更新
为了澄清,我知道如果lambda的签名匹配,lambda可以被转换为函数指针。我的问题是另一个方面。
ISO C标准保证功能可以前后进行,而不会失去任何精度。换句话说,以下表达式有效:
int f(int a){...}
void (*void_f)() = (void (*)())f;
int (*restored_f)(int) = (int (*)(int))void_f;
restored_f(10);
我的问题是根据C ++ 11,以下表达式是否也有效:
int (*f)(int) = [](int a) -> int {};
void (*void_f)() = (void (*)())f;
int (*restored_f)(int) = (int (*)(int))void_f;
restored_f(10);
答案 0 :(得分:0)
Lambdas没有捕获are implicitly convertible指向标准的函数的指针。虽然目前并非所有编译器都支持此功能(https://stackoverflow.com/a/2935230/261217)。
然后您可以显式地将函数指针强制转换为GCallback
。
答案 1 :(得分:0)
以下代码编译并适用于我(MSVC 2013):
auto lambdaFunc = [](int a, char b) -> int { return 0; };
typedef int (*LambdaType)(int, char);
GCallback fnTest1 = G_CALLBACK((LambdaType)lambdaFunc);
GCallback fnTest2 = G_CALLBACK((LambdaType) [](int a, char b) -> int { return 0; });
do_something(fnTest1);
do_something(fnTest2);
do_something(G_CALLBACK((LambdaType)lambdaFunc));