Generics for multiparameter C functions in C11

前端 未结 5 1346
独厮守ぢ
独厮守ぢ 2020-12-13 07:13

I understand C11 generics for one-parameter functions, like this: (from here)

#define acos(X) _Generic((X), \\
    long double complex: cacosl, \\
    double         


        
5条回答
  •  不思量自难忘°
    2020-12-13 07:43

    Since C doesn't have tuples, let's make our own tuples:

    typedef struct {int _;} T_double_double;
    typedef struct {int _;} T_double_int;
    typedef struct {int _;} T_int_double;
    typedef struct {int _;} T_int_int;
    
    typedef struct { T_double_double Double; T_double_int Int;} T_double;
    typedef struct { T_int_double Double;    T_int_int    Int;} T_int;
    
    #define typeof1(X)       \
    _Generic( (X),            \
        int:    (T_int){{0}},  \
        double: (T_double){{0}} )
    
    #define typeof2(X, Y)      \
    _Generic( (Y),              \
        int:    typeof1(X).Int,  \
        double: typeof1(X).Double )
    

    This is the client code:

    #include 
    #include "generics.h"
    
    #define typename(X, Y)               \
    _Generic( typeof2(X, Y),              \
        T_int_int: "int, int\n",           \
        T_int_double: "int, double\n",      \
        T_double_double: "double, double\n", \
        T_double_int: "double, int\n",        \
        default: "Something else\n"            )
    
    int main() {
        printf(typename(1, 2));
        printf(typename(1, 2.0));
        printf(typename(1.0, 2.0));
        printf(typename(1.0, 2));
        return 0;
    }
    

    And it works:

    ~/workspace$ clang -Wall -std=c11 temp.c
    ~/workspace$ ./a.out 
    int, int
    int, double
    double, double
    double, int
    

    Yes, you will still need to write code in an exponential size. But at least you will be able to reuse it.

提交回复
热议问题