显然,您想要为不同的数据多次调用一个函数(相同的函数)。 但是这些数据是作为数组传递的,根据定义,数组是存储多个相同类型数据项的一种结构。因此,最终没有特殊的结构来实现这一点,只需在普通的C语言中进行即可:
typedef .... MY_TYPE;
typedef void (*callback_ptr)(MY_TYPE param);
void my_func1(MY_TYPE param){
}
void my_funcN(MY_TYPE param) {
}
void for_each( MY_TYPE array[], size_t array_sz, callback_ptr f )
{
int i;
for (i = 0; i < array_sz; i++)
f(array[i]);
}
....
MY_TYPE my_array[100] = { ... };
size_t my_array_sz = sizeof my_array / sizeof my_array[0];
for_each(my_array, my_array_sz, my_func1);
for_each(my_array, my_array_sz, my_funcN);
尽可能避免在不严格需要时使用
void *
。也许在早期设计阶段,您不知道它将要处理的实际数据类型,但很明显,一旦编写了实际调用语句,您就必须放置参数并使用返回值,因此您就会坚持实际类型....这给了您有关如何声明回调指针和处理函数的提示。在函数调用中放置实际类型使编译器检查正确性,并且这是帮助您避免犯错误的一种方式。
通用函数在C中不受支持,但如果您想要一些排列方式,允许您编写其中某个数据类型为通用类型的函数,则可以使用宏模拟(必须非常小心地编写宏以使其工作,但可以实现非常好的近似)。
您可以使用
cpp
宏为每种类型定义不同的函数,例如:
func_def.h
#define FUNC(TYPE) \
void my_func_##TYPE( TYPE param ) \
{ \
\
}
然后在文件作用域中包含以下函数:
program.c
FUNC(int)
FUNC(double)
并且这将会扩展为:
void my_func_int( int param ) \
{ \
\
}
void my_func_double( double param ) \
{ \
\
}
你无论如何都会得到参数类型检查。如你所见,你必须在函数名中使用类型,因为C不支持函数重载(具有相同名称和不同参数列表的函数)。在这种情况下,
my_func_*
回调和
for_each_*
函数都必须定义,以便编译器进行完全的类型检查。
for_each
宏可以做你展示的事情,可能具有稍微更好的类型安全性。不过我不知道你为什么想要这样做,使用它很奇怪,而且最后那个防止空指针的保护条件如果有一天被忘记了会带来很多麻烦。 - Mat