_Generic 泛型编程(C11)

← C语言知识地图


C 没有函数重载,_Generic 是 C11 引入的编译期类型分发,用同一宏名按实参类型选不同实现,做出”类型泛型”效果(<tgmath.h> 就是靠它实现的)。

语法

_Generic(控制表达式, 类型1: 结果表达式1, 类型2: 结果表达式2, ..., default: 默认结果)

工作方式

  1. 只看类型:取控制表达式的类型(不求值,类似 sizeof
  2. 匹配分发:用该类型去关联列表找匹配项,返回对应的结果表达式
  3. 无匹配:没有 default 且类型对不上 → 编译错误

类型判定规则

规则说明
控制表达式不求值副作用不生效:_Generic(x++, int:1, default:0)x 不会自增
去除顶层限定符const int / volatile int 都按 int 匹配,不能同时列 int:const int:
数组→指针退化int arr[10] 的类型视为 int*
关联类型不能兼容两个关联写兼容类型(如 intsigned)→ 编译错误
未选中分支可”不存在”只要求选中的结果表达式合法,未选中的不被求值/检查

典型用法

① 按类型选格式串

#define MY_PRINT(x) _Generic((x), \
    int:    printf("%d\n", (x)), \
    double: printf("%f\n", (x)), \
    char*:  printf("%s\n", (x)), \
    default: printf("unknown type\n"))
 
MY_PRINT(42);      // 42
MY_PRINT(3.14);    // 3.140000
MY_PRINT("hello"); // hello

② 按类型选函数名(仿 <tgmath.h>

#define cbrt(X) _Generic((X), \
    long double: cbrtl, \
    default:     cbrt,  \
    float:       cbrtf)(X)

_Generic 的结果是个函数名,后面再 (X) 调用,实现”同名多态”。

③ 配合 typeof 做泛型运算

#define MAX(a, b) _Generic((a), \
    long long: llmax, \
    double:    fmax,   \
    default:   imax)(a, b)