我想使用相同的“通用”功能来管理各种实体。实体示意性声明为:
typedef struct {
prefix_t pfx;
int i1;
int i2;
int i3;
} entity_t;
即用于管理的类型定义的结构前缀(包含链接指针,标志等)和有效负载。每个实体类型只有一个这样的类型声明。
管家功能仅需要获得指向前缀的指针,这很容易,而该函数将“探索”有效负载以返回有意义的数量用于管家。
以二叉树管理为例:
void TreeInsert (prefix_t *a, prefix_t *b, int (*compare) (prefix_t *, prefix_t *));
并且在过程中,我有这样的呼叫:
if (0 > compare(a, b)) {
// a comes before b
} else {
// a is the same as b or comes after
};
很好。库函数编译时没有错误也没有警告。
但是很明显,compare函数不能仅引用前缀。它需要探测有效载荷才有用:
int comp_entity (entity_t *a, entity_t *b) {
return a->i1 - b->i1;
}
编译器在以下行上警告comp_entity:
TreeInsert (&a->pfx, &b->pfx, comp_entity);
由于库函数用于许多不同的“实体”,所以比较函数不能在调用时进行类型转换。无法为前缀键入compare函数的参数,否则无法访问有效负载。
我是否仅为了将比较传递给库函数的目的而定义特定的函数类型?类似于:
typedef int (func_cast *) (prefix_t *, prefix_t*);
和
TreeInsert (&a->pfx, &b->pfx, (func_cast)comp_entity);
我宁愿避免这种情况。这可能吗?
Nota:
我找到了create universal function pointer to any type C language和How do I quiet the C compiler about a function pointer takes any number of arguments?,但它们没有提供解决方案。
您的比较函数知道应为真正的类型,因此您将声明类型为prefix_t *
的参数,并将参数强制转换为函数内部:
int comp_entity (prefix_t *a, prefix_t *b) {
entity_t *ea = (entity_t *)a;
entity_t *eb = (entity_t *)b;
return ea->i1 - eb->i1;
}