在C中部分应用函数

时间:2014-04-30 01:37:06

标签: c function pointers currying

我有以下代码:

/* Function that takes a list and applies "function" to every element */
struct list *iter(struct list *l, void (*function)(struct list *a));

我有一个函数foo(arg1, arg2, struct list *a,我想要应用于列表中的每个元素。

我怎样才能实现这样的行为?在支持闭包或currying的编程语言中,我会将foo部分应用于arg1arg2,但在C中似乎是不可能的。

是否可以让函数返回指向函数bar(struct list *a) = foo(arg1, arg2, a)的指针?

3 个答案:

答案 0 :(得分:1)

不,在C中没有很好的办法。

可能的解决方案,按优先顺序排列:

  1. 以其他方式迭代结构,允许您自己应用该功能。
  2. 如果您在编译时可以知道arg1arg2,只需编写一个使用这些参数调用foo()的函数
  3. arg1arg2的值设为全局(或静态到文件)并在调用iter()之前设置它们。 (哎呀)在这种情况下,有关任何线程的通常警告都适用。
  4. 如果您正在使用GCC并且始终使用GCC,则可以使用Nested Functions
  5. Do something horrible with variadic functions

答案 1 :(得分:1)

  

我怎样才能实现这样的行为?在编程语言中   支持闭包或currying我会部分应用foo   arg1和arg2,但在C中似乎是不可能的。

一种方法是使用提供所需功能的C版本。 Blocks extension to C为您提供了封闭功能。

答案 2 :(得分:1)

根据您的功能定义:

struct list *iter(struct list *l, void (*function)(struct list *a));

我假设您的列表包含一系列struct list个对象(而不是具有单独的头部和节点类型的列表)。

为了使回调更普遍可用,您需要提供额外的参数,调用者可以根据自己的需要进行调整:

struct list *iter( struct list *l, void *arg, void (*function)(void *, struct list *));

iter内,您使用function(arg, l);

回调

然后以这种方式调用foo

struct foo_args { arg1_t arg1; arg2_t arg2; };   // at file scope

void handler(void *args, struct list *node)    // at file scope
{
    struct foo_args *p_args = args;
    foo(p_args->arg1, p_args->arg2, node);
}

// in a function
struct foo_args args = { arg1, arg2 };
iter(l, &args, handler);

目前您还没有使用function的返回值,通常这可以用于指示迭代是否应该中断的标志(例如,因为处理此节点失败,或者发现它在寻找什么。)