c - 在 C 中模拟 lambda 表达式的优雅方式

标签 c lambda

让我们考虑一下 C 程序的这种情况:

RESPONSE_CALLBACK_T response_callback = &response_callback_function;
SendRequest(param1, param2, response_callback);

SendRequest 函数可能会在网络服务器上发布一些数据或调用一些其他程序模块,这些模块应该在完成工作后触发回调。因此,在调用此函数时,我们需要指定一个指向我们定义的回调函数的指针。

是否有一种优雅的方式来编写类似于支持 lambda 表达式的高级 OPP 语言的代码,例如:

SendRequest(param1, param2, function(int responseCode) { print(responseCode) });

我怎样才能最好地模拟这种行为?

最佳答案

在标准 C 中,无法提供函数文字;函数指针必须指向顶级函数。也无法捕获未作为参数传递的局部变量。

但是,按照增加(所谓的)优雅和降低盈利能力(可能还降低可靠性)的顺序:

在您的示例中,您不需要中间变量 response_callback。在 C 中,typedef 只是类型的别名,如果函数的签名与 RESPONSE_CALLBACK 的签名匹配,您可以直接使用函数的名称:

SendRequest(param1, param2, response_callback_function);

函数指针也不需要 & 运算符。我发现按照 C 的优雅标准,这已经足够优雅了。

一些编译器,例如gcc,实现嵌套函数,它允许您在使用它的地方附近定义函数:

if (print_flag) {
    void func(int rc) { print(rc); }

    SendRequest(param1, param2, func);
}

嵌套函数结合 statement expressions , 这也是仅 some compilers 支持的非标准扩展, 可用于 write a lambda macro .我没有发现该站点上显示的宏特别优雅,但是如果您有回调类,例如事件处理程序,您可以简化宏(如果您愿意在整个过程中使用相同的硬编码参数名称):

#define handler(l_body) \
  ({ void l_anonymous(int rc) l_body l_anonymous; })

然后这样调用它:

SendRequest(param1, param2, handler({ print(rc); }));

(您可以将大括号作为宏的一部分,但回调中语句后的分号看起来很奇怪;我更喜欢将大括号放在客户端代码中。)

注意 这似乎是碰巧起作用的功能,而不是设计使然的功能。并且您不应将封闭函数的任何局部变量用于可能在这些变量的生命周期结束时调用的回调。 (它会编译,但会导致运行时错误。)小心进行。

有些编译器可能对真正的 lambda 表达式或函数字面量有扩展,但我不知道。

关于c - 在 C 中模拟 lambda 表达式的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25545030/

相关文章:

c - 我在哪里可以获得有关 C 语言返回调用的说明/手册页?

java - 如何使用 Java8 Lambda 表达式将 Set<String> 转换为 Long[] 数组

python - 在 python 中返回多个值并将它们附加到数据帧的唯一列

Python 初学者 - 使用 lambda 函数对元组进行排序

使用 C 压缩 double 值

c# - 使用 SWIG 获取 C 结构来记住 C# 更改?

c# - 哪个更利于可读性?

c - switch 语句汇编代码到c

java - 在 Java8 中合并两个函数

lambda - 大家一直在说的 'Lambda'是什么?