【发布时间】:2020-11-07 22:51:54
【问题描述】:
这是一个 MRE
#include <string.h>
typedef char* mytype;
typedef int(*cmp)(const mytype, const mytype);
void foo(cmp f) {}
int main(void) {
foo(strcmp);
}
当我编译时,我得到:
$ gcc mre.c -Wall -Wextra
mre.c: In function ‘foo’:
mre.c:7:14: warning: unused parameter ‘f’ [-Wunused-parameter]
7 | void foo(cmp f) {}
| ~~~~^
mre.c: In function ‘main’:
mre.c:10:9: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]
10 | foo(strcmp);
| ^~~~~~
| |
| int (*)(const char *, const char *)
mre.c:7:14: note: expected ‘cmp’ {aka ‘int (*)(char * const, char * const)’} but argument is of type ‘int (*)(const char *, const char *)’
7 | void foo(cmp f) {}
| ~~~~^
第一个警告无关紧要。但是第二个我该怎么办?我尝试将 typedef 更改为:
typedef int(*cmp)(mytype const,mytype const);
但这给出了完全相同的结果。当我改为:
typedef int(*cmp)(const char*, const char*);
它起作用了,但出于显而易见的原因,这并不可取。另一件有效但也不可取的事情是:
typedef const char* mytype;
typedef int(*cmp)(mytype, mytype);
那么我在这里错过了什么?
我要解决的问题是我想创建一个通用结构,其中数据的类型为mytype。该结构的用户应实现比较功能,但我希望它与strcmp 一起工作,以防mytype 的类型为char*。
请注意,mytype 不一定需要是指针。这取决于用户指定的数据类型。另外,我知道 typedefing 指针通常是不好的做法,但我认为这是一种特殊情况,因为我想 typedef 无论类型是什么,它可能是一个指针。
结构如下:
struct node {
struct node *next;
mytype data;
};
我设法用#define mytype char* 解决了这个问题,但感觉非常难看,如果有其他方法,我更愿意。我希望它是可移植的,所以我不想使用 gcc 扩展。
【问题讨论】:
-
这能回答你的问题吗? typedef pointer const weirdness
-
mytype的 typedef 应该是typedef char mytype;以便mytype实际上是一个类型,而不是一个指向类型的指针。那么函数的 typedef 是typedef int (*cmp)(const mytype *, const mytype *);当mytype只是一个类型时,你可以完全控制装饰器的顺序。 -
我想我会选择
foo((cmp)strcmp); -
建议您检查
qsort()函数的源代码,因为这需要用户编写比较函数。
标签: c pointers constants typedef