将成员 C 函数指针分配给另一个成员作为默认参数
assign member C function pointer with another member as default argument
假设我有一个 C 结构
struct MULTIPLY{
int by; //some factor to multiply, can be seen as instance id/key
int (*get)(int c); //the function that actually returns the result
} multiply;
并且我想使用以下函数multiply分配实例
int product(int a, int b)
{
return a*b;
}
在 main 中,我想分配给 multiply->get 一个计算 multiply->by 和 a 的乘积的函数新论点。我可以通过传递一个指向乘法实例的指针来做到这一点,但我想知道是否有任何方法可以在不更改 get 函数
的签名的情况下调用它
multiply->by = 2;
multiply->get(int c) = product(multiply->by, c); ???
multiply->get(5); // 10
谢谢!
编辑:
感谢您的回答。实际上,默认情况下无法在 C 中执行闭包。我一直在寻找解决方法。我找到了 2 个解决方案,但非常有限。一个是 Blocks.h (也适用于 obj-C)需要用 Clang 编译。另一个是 FFCALL (http://www.haible.de/bruno/packages-ffcall-README.html ),它仅限于某些处理器架构。
因此,就我而言,我决定只传递一些指针来访问 id(在本例中为 by)。几乎是 Tomasz Lewowski 建议的内容。
不,你不能像在 C 中那样做闭包。
您也不能 运行-time 定义函数,因为 C 是一种编译语言,当代码 运行s.
时编译器不可用
一般C不支持部分函数应用,你需要在编译时设置所有签名和名称,函数一般不能在运行时定义(内核可以加载它们,但我们忽略它 - 用户空间应用程序不不要这样做)。然而...
在某种抽象层次上这是可能的(例如,许多用 C 编写的解释器允许这样做),但对于纯 C 来说,这不是直接可能的,如果你需要这样做,您可能选择了错误的语言。
您可以通过模拟面向对象的方法(始终将另一个参数作为 this
指针传递)来解决它。伪代码:
struct MULTIPLY{
int by; //some factor to multiply, can be seen as instance id/key
// intended private
int (*f)(int, int);
} multiply;
int call(MULTIPLY m, int i) {
return *(m.f)(by, i);
}
MULTIPLY m = {2, product} // + allocation etc.;
call(m, 5); // actual call
它在真正支持面向对象设计的语言中要好得多,但你也可以在 C 中做到这一点 - 不过,你需要记住这个额外的参数(this
,context
,self
或者你想怎么称呼它),这有点搞乱了代码。
如果您下定决心不考虑任何其他参数就这样做,您可以创建一个全局 MULTIPLY
实例并在 call
中使用它。这将是这样的:
// global scope!
MULTIPLY m;
int call(int i) {
return *(m.f)(m.by, i);
}
// m initialization etc.
// some stuff happening
call(5);
但是,请不要。由于全局绑定,维护起来会非常困难。另外,它不会像闭包一样工作——一旦你改变 m
中的值,你通过 call
的所有地方将开始表现不同(以前,面向对象的方法将在任何地方正常工作).
假设我有一个 C 结构
struct MULTIPLY{
int by; //some factor to multiply, can be seen as instance id/key
int (*get)(int c); //the function that actually returns the result
} multiply;
并且我想使用以下函数multiply分配实例
int product(int a, int b)
{
return a*b;
}
在 main 中,我想分配给 multiply->get 一个计算 multiply->by 和 a 的乘积的函数新论点。我可以通过传递一个指向乘法实例的指针来做到这一点,但我想知道是否有任何方法可以在不更改 get 函数
的签名的情况下调用它multiply->by = 2;
multiply->get(int c) = product(multiply->by, c); ???
multiply->get(5); // 10
谢谢!
编辑:
感谢您的回答。实际上,默认情况下无法在 C 中执行闭包。我一直在寻找解决方法。我找到了 2 个解决方案,但非常有限。一个是 Blocks.h (也适用于 obj-C)需要用 Clang 编译。另一个是 FFCALL (http://www.haible.de/bruno/packages-ffcall-README.html ),它仅限于某些处理器架构。
因此,就我而言,我决定只传递一些指针来访问 id(在本例中为 by)。几乎是 Tomasz Lewowski 建议的内容。
不,你不能像在 C 中那样做闭包。
您也不能 运行-time 定义函数,因为 C 是一种编译语言,当代码 运行s.
时编译器不可用一般C不支持部分函数应用,你需要在编译时设置所有签名和名称,函数一般不能在运行时定义(内核可以加载它们,但我们忽略它 - 用户空间应用程序不不要这样做)。然而...
在某种抽象层次上这是可能的(例如,许多用 C 编写的解释器允许这样做),但对于纯 C 来说,这不是直接可能的,如果你需要这样做,您可能选择了错误的语言。
您可以通过模拟面向对象的方法(始终将另一个参数作为 this
指针传递)来解决它。伪代码:
struct MULTIPLY{
int by; //some factor to multiply, can be seen as instance id/key
// intended private
int (*f)(int, int);
} multiply;
int call(MULTIPLY m, int i) {
return *(m.f)(by, i);
}
MULTIPLY m = {2, product} // + allocation etc.;
call(m, 5); // actual call
它在真正支持面向对象设计的语言中要好得多,但你也可以在 C 中做到这一点 - 不过,你需要记住这个额外的参数(this
,context
,self
或者你想怎么称呼它),这有点搞乱了代码。
如果您下定决心不考虑任何其他参数就这样做,您可以创建一个全局 MULTIPLY
实例并在 call
中使用它。这将是这样的:
// global scope!
MULTIPLY m;
int call(int i) {
return *(m.f)(m.by, i);
}
// m initialization etc.
// some stuff happening
call(5);
但是,请不要。由于全局绑定,维护起来会非常困难。另外,它不会像闭包一样工作——一旦你改变 m
中的值,你通过 call
的所有地方将开始表现不同(以前,面向对象的方法将在任何地方正常工作).