在程序设计中,泛型编程(generic programming)指那些没有特定类型,但是一旦指定一种类型,就可以转换成指定类型的代码。例如,C++ 在模板中可以创建泛型算法,然后编译器根据指定的类型自动使用实例化代
码。
C 没有这种泛型编程。然而,C11 新增了一种表达式,叫作泛型选择表达式(generic selection expression),可根据表达式的类型(即表达式的类型是 int、double 还是其他类型)选择一个值。泛型选择表达式不是预处理器指令,但是在一些泛型编程中它常用作 #define 宏定义的一部分。
下面是一个泛型选择表达式的示例:
_Generic(x, int: 0, float: 1, double: 2, default: 3)
_Generic 是 C11 的关键字。_Generic 后面的圆括号中包含多个用逗号分隔的项。第1个项是一个表达式,后面的每个项都由一个类型、一个冒号和一个值组成,如 float: 1。第1个项的类型匹配哪个标签,整个表达式的值是该标签后面的值。例如,假设上面表达式中 x 是 int 类型的变量,x 的类型匹配 int: 标签,那么整个表达式的值就是 0。如果没有与类型匹配的标签,表达式的值就是 default: 标签后面的值。泛型选择语句与 switch 语句类似,只是前者用表达式的类型匹配标签,而后者用表达式的值匹配标签。
#define MYTYPE(X) _Generic((X),\int: "int",\float : "float",\double: "double",\default: "other"\)
宏必须定义为一条逻辑行,但是可以用 \ 把一条逻辑行分隔成多条物理行。在这种情况下,对泛型选择表达式求值得字符串。例如,对 MYTYPE(5) 求值得 “int”,因为值 5 的类型与 int: 标签匹配。
// mytype.c#include <stdio.h>#define MYTYPE(X) _Generic((X),\int: "int",\float : "float",\double: "double",\default: "other"\)int main(void){int d = 5;printf("%s\n", MYTYPE(d)); // d 是int类型printf("%s\n", MYTYPE(2.0*d)); // 2.0 * d 是double类型printf("%s\n", MYTYPE(3L)); // 3L是long类型printf("%s\n", MYTYPE(&d)); // &d 的类型是 int *return 0;}
// 输出结果:
int
double
other
other
