# _Generic 選擇

C11 提供了 `_Generic` 選擇，用來模擬泛型程式，其本質是類似 `switch` 的選擇陳述，不過是編譯時期根據型態來選擇展開的對象。例如：

``````#define V_TYPE 0
#define WAT _Generic(V_TYPE, float: 2.0,     \
char *: "XD",   \
int: 10,        \
default: 'a')
``````

``````#include <stdio.h>
#include <math.h>

int main(void) {
double x = 8.0;
const float y = 3.375;
printf("cbrt(8.0) = %f\n", cbrt(x));
printf("cbrtf(3.375) = %f\n", cbrtf(y));

return 0;
}
``````

``````#include <stdio.h>
#include <math.h>

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

int main(void){
double x = 8.0;
const float y = 3.375;
printf("cbrt(8.0) = %f\n", cbrt(x));
printf("cbrtf(3.375) = %f\n", cbrt(y));

return 0;
}
``````

`cbrtf(3.375)` 為例，`x``float` 型態，`_Generic` 透過第一個 `(X)` 展開後的 `(3.375)` 比對後選擇預設的 `cbrtf`，之後結合第二個 `(X)` 展開後的 `(3.375)` 成為 `cbrtf(3.375)`

``````#include <stdio.h>

#define foo(a, b) _Generic((a), int: foo1,     \
default: foo2  \
)(a, b)

void foo1(int a, int b) {
printf("%d %d\n", a, b);
}

void foo2(double a, int b) {
printf("%f %d\n", a, b);
}

int main(void){
foo(1, 10);
foo(1.0, 10);

return 0;
}
``````

``````#include <stdio.h>
#include <math.h>

#define foo(a, b)                \
_Generic((a),                \
int: foo1,               \
double: _Generic((b),    \
int : foo2,  \
double: foo3 \
)                \
)(a, b)

void foo1(int a, int b) {
printf("%d %d\n", a, b);
}

void foo2(double a, int b) {
printf("%f %d\n", a, b);
}

void foo3(double a, double b) {
printf("%f %f\n", a, b);
}

int main(void){
foo(1, 5);
foo(1.0, 10);
foo(1.0, 3.14);

return 0;
}
``````