C中的异构函数指针数组
Array of heteregenous function pointers in C
我想要一个函数指针数组,每个指针指向不同的函数。该函数在原型和参数数量方面也可能有所不同。
我正在C/C++中寻找以下类似的功能。
以下代码在C 中不可编译
#include <stdio.h>
typedef int (*FUNC)(int a,int b);
int func_one(int a)
{
printf("n In function 1 with 1 parameter %d n",a);
return 1;
}
int func_two(int a,int b)
{
printf("n In function 2 with 2 parameter %d %d n",a,b);
return 2;
}
typedef struct{
FUNC fnc;
enum type{ ONE,TWO} type_info;
}STR;
int main()
{
STR str[2];
int ret;
int i;
str[0].fnc = func_one;
str[0].type_info = ONE;
str[1].fnc = func_two;
str[1].type_info = TWO;
for(i=1;i>=0;--i)
{
if(str[i].type_info == ONE)
ret = str[i].fnc(10);
else if(str[i].type_info == TWO)
ret = (str[i].fnc)(10,20);
else
perror("error in implementation n");
printf("n return value is %d n",ret);
}
return 0;
}
在C中,从一种函数指针类型转换为另一种是安全的(只要您为了调用它而将其反向转换),因此您可以声明一种"通用函数指针类型":
typedef void (*GENFUNC)(void);
然后根据需要铸造:
GENFUNC tmp = (GENFUNC)&func_two; // cast to generic pointer
FUNC two = (FUNC)tmp; // note: have to cast it back!
two(0, 1);
这似乎不是一个好主意。但如果你真的需要这个,那么你应该考虑使用一个联合:
typedef struct{
union{
int (*f1)(int);
int (*f2)(int,int);
} fnc;
enum type{ ONE,TWO} type_info;
}STR;
如果你知道所有不同的可能类型,你可以这样做:
typedef int (*FUNC1)(int a);
typedef int (*FUNC2)(int a,int b);
typedef struct{
union {
FUNC1 one_arg;
FUNC2 two_arg;
} fnc;
enum type{ ONE,TWO} type_info;
} STR;
如果你不知道它们,但无论何时使用,你都可以设法找出正确的表格,你可以简单地使用:
typedef struct{
void *fnc;
enum type{ ONE,TWO} type_info;
} STR;
或者以非常通用的形式:
typedef struct{
void *func;
char *return_type;
char *args_type;
} STR;
其中CCD_ 1是每个k个字母显示一个可能的参数类型的字符串。与return_type
相同,只是它也可以包含void
的"v"
。
然后,每当你想使用函数时,你必须查看return_type和args_type,并决定将func
大小写为哪个原型。这在某种程度上类似于C++中的名称篡改(尽管使用名称篡改,函数名称本身用args_type
符号装饰,而不是保留另一个字符串)
typedef int (*FUNC)(void);
typedef int (*FUNC_1p)(int);
typedef int (*FUNC_2p)(int, int);
typedef struct
{
FUNC fnc;
enum type { ONE, TWO } type_info;
} STR;
if ( str[i].type_info == ONE )
{
FUNC_1p f = str[i].fnc;
ret = f(10);
}
else if ( str[i].type_info == TWO )
{
FUNC_2p f = str[i].fnc;
ret = f(10,20);
}
它编译并运行。不过这不是个好主意。
C中的"泛型"函数将使用一个void*指针,然后必须将void*强制转换为数据。
您可以创建几个不同的特殊类型的版本,这些版本将始终对"已知"类型进行操作,这样它们就可以将void*强制转换为该函数的特定类型,但签名将采用void*参数,这样您就可以在函数数组中存储多个参数。
例如
typedef int (GENERIC_FUNC*)(void* genericData);
struct A
{
int x;
int y;
};
int GenericAFunc( void * ptr )
{
A* a = (A*)(ptr);
return a->x + a->y;
}
GENERIC_FUNC * funcs[1];
funcs[0] = GenericAFunc;
这些函数都将返回int,但如果您希望它们生成不同的结果集,它们也可以在a结构中设置结果。
将函数定义为接受可变数量的参数:
typedef int (*FUNC)(int a, ...);
然后简单地选一个有趣的:
str[0].fnc = (FUNC) func_one;
str[1].fnc = (FUNC) func_two;
你可以像现在一样调用func:
if(str[i].type_info == ONE)
ret = str[i].fnc(10);
else if(str[i].type_info == TWO)
ret = str[i].fnc(10,20);
这是可能的,因为可变参数函数允许您向其传递任意数量的整数。
我不确定这是否符合您的实际需求,但您可以使用从公共基类派生的函子:
#include <cstdio>
struct FUNC {
enum type {INVALID, ONE, TWO} type_info;
virtual int operator()(int) { return -1; }
virtual int operator()(int, int) { return -1; }
FUNC(type t=INVALID) : type_info(t) {}
};
struct func_one : FUNC {
func_one() : FUNC(ONE) {}
int operator()(int) { return 1; }
};
struct func_two : FUNC {
func_two() : FUNC(TWO) {}
int operator()(int, int) { return 2; }
};
int main () {
FUNC* str[2] = { new func_one(), new func_two() };
int ret;
int i;
for(i = 1; i>=0; --i) {
if(str[i]->type_info == FUNC::ONE)
ret = (*str[i])(10);
else if(str[i]->type_info == FUNC::TWO)
ret = (*str[i])(10,20);
else
throw 1;
printf("Return value is %dn", ret);
}
}
- 指向指向字符数组的指针数组的指针
- 通过指向指针数组的指针访问子类的属性
- C++,指针数组,指向双链表中的条目
- 在C++中,如何初始化指向wchar_t*的指针数组(生成wchar_t**)
- C++从函数指针数组调用函数
- 关于指向指针数组的指针
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 将链表转换为指针数组时出错
- C++ 对象指针数组的复制构造函数
- C++ - 循环访问指针数组会导致错误
- 删除指针数组 (C++) 中的元素
- 如何循环访问 cpp 中的函数返回的字符指针数组
- 将函数指针数组中的函数指针作为模板参数传递
- Google Or-Tools Glop:如何创建指向 const 对象的指针数组?
- 具有推导参数的模板函数指针数组变量
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- C++指针数组到字符数组中的特定位置
- 如何在C++中复制指针数组的数据
- 初始化类中的指针数组,并在另一个类中检索它
- 尽管直接设置了指针数组,但仍为空