C++11 使用C++;11 lambda作为GObject库中的回调

C++11 使用C++;11 lambda作为GObject库中的回调,c++11,lambda,gobject,C++11,Lambda,Gobject,不捕获任何内容的C++11 lambda可以存储在函数指针中。只需确保lambda接受并返回与函数指针相同的参数 在库中,所有回调都具有类型void(*GCallback)(void)。此定义无论如何不会影响回调的签名,但: 在结构定义和定义中用于回调函数的类型 函数签名。这并不意味着所有回调函数 必须不带参数并返回void。所需的签名 回调函数由使用的上下文决定(例如。 它所连接的信号)。使用G_CALLBACK()来强制转换 GCallback的回调函数 换句话说,可以传递如下函数: int

不捕获任何内容的C++11 lambda可以存储在函数指针中。只需确保lambda接受并返回与函数指针相同的参数

在库中,所有回调都具有类型
void(*GCallback)(void)
。此定义无论如何不会影响回调的签名,但:

在结构定义和定义中用于回调函数的类型 函数签名。这并不意味着所有回调函数 必须不带参数并返回void。所需的签名 回调函数由使用的上下文决定(例如。 它所连接的信号)。使用G_CALLBACK()来强制转换 GCallback的回调函数

换句话说,可以传递如下函数:

int my_function(int a, char b) {}
通过强制转换其类型(G_回调就是这么做的):

不幸的是,类型转换不适用于C++11 lambdas:

do_something(G_CALLBACK([](int a, char b) -> int {...});
// Cannot cast from type lambda to pointer type GCallback
< P>是否可以使用任意类型的C++ LAMBDAS代替GACBACK?

更新

我只想澄清一下,我知道如果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);
lambda没有捕获到标准函数的指针。尽管目前并非所有编译器都支持此功能()


然后,您可以显式地将函数指针强制转换为
GCallback

以下代码编译并适用于我(MSVC 2013):


我自己没有尝试过,但是您可以尝试将lambda存储为变量(
auto-fun=[](…){…};
),然后在
do\u something
调用中执行显式强制转换(
do\u something(reinterpret\u cast(fun));
)。因为我还没有试过,所以我不知道它是否有效。@icepack这个问题不是关于如何使用lambdas代替函数指针。这是关于如何(如果可能的话)使用任意类型的lambda来代替GCallback。@Kentzo我理解这一点。如果你仔细观察这个答案,你会发现用lambda替换C指针并不总是可能的。请参阅我问题的更新。第二个表达式在C++11下是否有效?如果是的话,你能指出标准吗?我认为在这个转换中没有问题,lambda函数只是一个匿名类的方法。它和正常函数一样存在。但我不能指出标准,对不起,我太懒了:)
int (*f)(int) = [](int a) -> int {};
void (*void_f)() = (void (*)())f;
int (*restored_f)(int) = (int (*)(int))void_f;
restored_f(10);
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));