【发布时间】:2015-02-12 23:35:30
【问题描述】:
我正在实现一个通用的单链表,其中列表节点存储指向其数据的指针。
typedef struct sll_node
{
void *data;
struct sll_node *next;
} sll_node;
为了实现一个适用于任何类型数据的通用查找子例程,我编写了它,以便将指向比较函数的函数指针作为参数,如下所示:
/* eq() must take 2 arguments. ex: strcmp(char *, char *) */
sll_node *sll_find(void *data, int (*eq)(), sll_node *root);
您可以传递适用于手头数据类型的适当函数指针。因此,如果您将字符串存储在列表节点中,则可以将 strcmp 作为 eq() 函数传递,依此类推。它有效,但我仍然不满意..
有没有办法在不放弃通用性的情况下明确指定比较函数参数的个数?
我一开始试过这个:
sll_node *sll_find(void *data, int (*eq)(void *, void *), sll_node *root);
我预计它会起作用。但是没有(编辑:它编译时出现警告,但我打开了 -Werror!),我必须围绕 strcmp 编写一个包装函数以使其符合 eq 原型。
然后我尝试了:
sll_node *sll_find(void *data, int (*eq)(a, b), sll_node *root);
或:
typedef int (*equality_fn)(a, b);
sll_node *sll_find(void *data, equality_fn eq, sll_node *root);
这两个都不会编译,因为:“没有类型的参数列表只允许在函数定义中”
【问题讨论】:
-
比较函数通常使用
const关键字声明,例如int (*eq)(const void *, const void *)。这是否解决了strcmp的问题? -
转换指针的类型需要一个参数;在你的情况下,也许尝试循环直到 NULL?
-
@user3386109 你对 const 关键字是正确的(从惯用的角度来看),但它仍然给出相同的警告:警告:不兼容的指针类型将 'int (const char , const char *)' 传递给 'int ()(void *, void *)' [-Wincompatible-pointer-types] 类型的参数(我编辑要澄清的问题)
-
@concacid 我在等待您的回复时尝试了代码。为了在没有包装器的情况下使用
strcmp,您需要完全匹配strcmp,这意味着使用const char *作为参数。您也许还可以投射strcmp。如果可行,我会尝试并将其添加到下面的答案中。 -
@concacid 将
strcmp转换为适当的类型可以工作。我已将其添加到我的答案中。
标签: c function-pointers