c语言里面使用泛型,高版本clang和gcc都支持。
一直想要用c实现一个比较好操作的hashtable,类似这种接口hash_table_insert(hashtable, key, value), 网上大家的实现都是声明key,value参数为void *, 这样的操作个人感觉非常麻烦,我想要的是使用者无需关心key和value的类型,直接插入,变得和动态类型语言一样。
c没有java, C++那种泛型模板,也不像动态语言变量可以无需指定类型,然后我搜索发现c11标准已经加入了generics, gcc和clang编译器已经提供_Generic这个宏,vs不支持,因为vs好像宣布永远只支持c89,不会再改进了,具体可以参考这里学习,可以识别参数的类型,那么问题就解决了! 使用起来非常简单,下面是我在我实现的hashtable中定义的宏
#define hash_table_insert(table, key, value) _Generic((value),\
_Bool: hash_table_insert_bool, \
short int: hash_table_insert_long, \
unsigned short int: hash_table_insert_long, \
int: hash_table_insert_long, \
unsigned int: hash_table_insert_long, \
long int: hash_table_insert_long, \
unsigned long int: hash_table_insert_long, \
long long int: hash_table_insert_long, \
unsigned long long int: hash_table_insert_long, \
float: hash_table_insert_double, \
double: hash_table_insert_double, \
char *: hash_table_insert_string, \
default: unsupport_type)((table), (key), (value))
使用的时候,比如像我这个接口,最好就是显示指定值得类型,就像下面这样,否者可能得不到你预期的结果
char *a = "hello";
bool b = true;
long c = 1;
double d = 1.1;
char e = 'c';
hash_table_insert(hashtable, "string", a);
hash_table_insert(hashtable, "bool", b);
hash_table_insert(hashtable, "long", c);
hash_table_insert(hashtable, "double", d);
hash_table_insert(hashtable, "unsupport type", e);
hash_table_print(hashtable);
因为如果你直接使用true去尝试插入,本质上true和false在stdbool.h中的定义是宏,值是0和1,0和1在c语言默认不指定类型是int,而不是你想插入的bool类型了。
编译器是使用啥黑科技判断类型的?我自己只能想到类型字长,在64位系统上,比如char的sizeof是1,int是4, char *是8,但是如果再来个void *或者long,都是8个字节的长度,就无法解决了,知道的欢迎留言!
评论
暂无评论~~