假设我想用普通的 C 实现一个数值积分例程。它看起来像这样:
double integrate(double (*f)(double), double lower, double upper, double step));
我经常发现实际上依赖于多个变量的函数,我想整合第一个。说我想整合这个:
double func(double x, double z);
关于
x
。我无法将 func
传递给 integrate
,因为它的签名错误。现在我知道了以下变通方法,这些变通方法是我们在学习数字类(class)时采用的:我刚刚使用 C++ 和 ist
std::bind
创建了一个可以传递给集成例程的仿函数(函数对象)。现在我只想使用 lambda 函数来完成它。 使用 GCC,您可以在函数中声明一个函数。所以可以做
// z is set to some value in this function scope here.
double inner(double x) {
return func(x, z);
}
并将该
inner
传递给 integrate
函数。这是不标准的,感觉不太好。 z
的值可以存储在一个全局变量中。这将需要函数 func
是可编辑的,以使用全局变量中的 z
而不是参数。那可能是不可能的。然后它也会破坏并发性并且总体上很糟糕。 在不破坏某些东西的情况下,是否存在与纯 C 相关的方法?
最佳答案
此问题的一种常见解决方案是将设计更改为:
double integrate(double (*f)(double, void*), void*,
double lower, double upper, double step);
在这里,您将额外的
void *
传递给 integrate
,然后将其传递回 f
。这可用于传递任意数据,在您的情况下,您将传递一个指向 z
的指针,并且在函数 f
中,您将指针转换回其原始类型并恢复值 z
。这种模式在 C 库中无处不在,例如这里是 pthread_create 的原型(prototype):int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
关于使用 ISO C99 进行柯里化/绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23849343/