【C】利用 _Generic 重载 参数数目不同的函数
< 看之前需要先了解一下_Generic 的基本用法 -- 周树人 >
形式:
这是两个 链表初始化函数:
Link_t void_init (Link_t _head); // initalize the head Link_t arr_init (Link_t _head, int32_t* _arr, size_t _lenth); // initalize with an arr
我们使用 _Generic关键字和可变参数 来模拟 模板和缺省参数:
#define init(...) \ _Generic(&(uintptr_t[]){(uintptr_t)__VA_ARGS__},\ uintptr_t(*)[3] : arr_init, \ default : void_init)(__VA_ARGS__) // 泛型初始化
分析:
#define init( ~ ) _Generic( ~ ) //宏替换 _Generic 为我们需要的 init 函数
由于我们两个函数的参数数量不同,所以我们使用 可变参数:
#define init( ... ) _Generic( ~ )(__VA_ARGS__) // ... 和 __VA_ARGS__ 就是可变参数的基本形式, __VA_ARGS__ 会引用 ... 接收到的参数
_Generic 里面:
&(uintptr_t[]){(uintptr_t)__VA_ARGS__} /*这句话的基本形式是 {__VA_ARGS__},这是一个数组,用于存放接收到的参数 *我们将它强制转换为 uintptr_t 类型(unsigned long long), 这个类型一般用于存取指针数据,因为它足够大, 所以一般不会丢失数据 *为什么我们需要这样转换数据类型? 因为在这两个函数里面,参数类型也是不同的,数组无法存储不同类型的参数
*数组完成之后我们将它再转换为 uintptr_t[]这样一个数组,取这个数组的地址进行比较(数组本体太大了_Generic无法直接比较) */
uintptr_t(*)[3] : arr_init, default : void_init /* 对第一个参数进行选择: * 在上面我们取的是数组的地址,自然就要数组指针来匹配 * 如果有3个参数,那么宏替换为arr_init函数 * 默认替换为 void_init 函数 */

浙公网安备 33010602011771号