我认为以下代码描述了我想要做的事情。具体来说,我希望将函数指针强制转换为泛型函数类型,唯一的区别在于签名是不同的指针类型。
现在,我知道要求函数指针兼容,如this question中所述,但我不确定是否有不同指针类型的参数满足兼容性要求。
代码编译并运行,但是,正如预期的那样,从不兼容的指针类型给出有关赋值的警告。有没有办法满足编译器并实现我的目标?
#include <stdio.h>
int float_function(float *array, int length)
{
int i;
for(i=0; i<length; i++){
printf("%f\n", array[i]);
}
}
int double_function(double *array, int length)
{
int i;
for(i=0; i<length; i++){
printf("%f\n", array[i]);
}
}
int main()
{
float a[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
double b[5] = {0.0, 1.0, 2.0, 3.0, 4.0};
int (*generic_function)(void*, int) = NULL;
generic_function = &float_function;
generic_function(a, 5);
generic_function = &double_function;
generic_function(b, 5);
return 0;
}
答案 0 :(得分:5)
最干净的方式是恕我直言,在内部执行函数。这将强制所有函数签名相同,并使演员表不受调用者代码的影响。 (例如qsort()想要它的方式)
int double_function(void *p, unsigned size)
{
double *array = p
unsigned uu;
for(uu=0; uu < size; uu++){
printf("%f\n", array[uu]);
}
return 42;
}
答案 1 :(得分:2)
是的,在没有原型的情况下声明它。
int (*generic_function)() = NULL;
现在您可以分配任何返回int
的函数,但也可以传递任何参数,并且编译器不需要拒绝不兼容的参数。
答案 2 :(得分:1)
((int(*)(float*,int))generic_function)(a, 5);
另一个解决方案(灵感来自@wildplasser的答案)是将函数包含在函数中,取无效*并对该参数执行强制转换。 “通过宏”这样做很简单;
#define WRAP(FN, TYPE) int FN##_wrapped(void* p, int len) { return FN((TYPE*)p, len); }
WRAP(float_function, float)
WRAP(double_function, double)
然后你可以改用以下相当简洁的线条;
generic_function = float_function_wrapped;
generic_function(a, 5);
也就是说,指针转换通常不是我所倡导的解决方案,但它有其用例。