C 中的通用函数指针
我有一个函数,它接受一个数据块和该块的大小以及一个函数指针作为参数。然后它迭代数据并对数据块的每个元素执行计算。 以下是我正在做的事情的基本概要:
int myfunction(int* data, int size, int (*functionAsPointer)(int)){
//walking through the data and calculating something
for (int n = 0; n < size; n++){
data[n] = (*function)(data[n]);
}
}
我作为参数传递的函数看起来像这样:
int mycalculation(int input){
//doing some math with input
//...
return input;
}
这运行良好,但现在我需要将一个附加变量传递给我的函数指针。 有没有
int mynewcalculation(int input, int someVariable){
//e.g.
input = input * someVariable;
//...
return input;
}
一种优雅的方式来实现这一点,同时保持我的整体设计理念?
I have a function which takes a block of data and the size of the block and a function pointer as argument. Then it iterates over the data and performes a calculation on each element of the data block.
The following is the essential outline of what I am doing:
int myfunction(int* data, int size, int (*functionAsPointer)(int)){
//walking through the data and calculating something
for (int n = 0; n < size; n++){
data[n] = (*function)(data[n]);
}
}
The functions I am passing as arguments look something like this:
int mycalculation(int input){
//doing some math with input
//...
return input;
}
This is working well, but now I need to pass an additional variable to my functionpointer. Something along the lines
int mynewcalculation(int input, int someVariable){
//e.g.
input = input * someVariable;
//...
return input;
}
Is there an elegant way to achieve this and at the same time keeping my overall design idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使其完全通用的常用方法是使用 void*,这当然会导致各种类型安全问题:
要传入的任何给定函数都必须具有该原型,但您可以通过 userdata 推送任何您想要的数据。完全没有类型检查。
您还可以按照 dbingham 的建议使用 va_args ;但这实际上并没有太大不同,因为要映射的函数的原型必须是
int(int, va_list)
。编辑:我喜欢
void*
方法。无论如何,va_list
不会添加任何类型安全性,并且会增加更多潜在的用户错误(特别是调用va_end
两次或未正确实现va_arg
循环) 。 void* 也不会添加任何额外的代码行;它被干净地传递了,用户只需将其取消引用为(希望)正确的类型(在一般情况下,这可能是一个结构体)。The usual way to make it totally generic is with a void*, which of course causes all kinds of typesafety issues:
Any given function to be passed in must have that prototype, but you can shove any data you want in through
userdata
. There's just absolutely no typechecking.You could also use va_args as dbingham suggests; this isn't really much different though, since the prototype for your function to map will have to be
int(int, va_list)
.Edit: I favor the
void*
approach. Theva_list
doesn't add any typesafety anyway and adds more potential for user error (particularly callingva_end
twice or not implementing theva_arg
loop right). The void* also doesn't add any extra lines of code; it's passed cleanly through, and the user just dereferences it into (hopefully) the right type (which is probably a struct, in the general case).