zoukankan      html  css  js  c++  java
  • C 基础 _Generic 泛型应用

    引言 - _Generic 用法简介

    #include <stdio.h>
    
    #define TYPENAME_CASE(type)                         
        type: #type,
    
    #define TYPENAME_POINTER_CASE(type)                 
        TYPENAME_CASE(type)                             
        TYPENAME_CASE(type *)                           
    
    #define TYPENAME_UNSIGNED_CASE(type)                
        TYPENAME_POINTER_CASE(type)                     
        TYPENAME_POINTER_CASE(unsigned type)            
    
    #define TYPENAME(x) _Generic((x),                   
        TYPENAME_POINTER_CASE(_Bool)                    
        TYPENAME_UNSIGNED_CASE(char)                    
        TYPENAME_UNSIGNED_CASE(short)                   
        TYPENAME_UNSIGNED_CASE(long)                    
        TYPENAME_UNSIGNED_CASE(long long)               
        TYPENAME_POINTER_CASE(float)                    
        TYPENAME_POINTER_CASE(double)                   
        TYPENAME_POINTER_CASE(long double)              
        TYPENAME_POINTER_CASE(float _Complex)           
        TYPENAME_POINTER_CASE(double _Complex)          
        TYPENAME_CASE(void *)                           
        default: "other"                                
    )
    
    int main(int argc, char * argv[]) {
        double _Complex c;
        double _Complex * p = &c;
    
        puts(TYPENAME(p));
    
        return 0;
    }

     

    { warning 点睛呀, GCC 亲自指出自己的 BUG} 

    正文 - _Generic 实现函数重载

    #include <stdio.h>
    
    void foo_void(void) {
        printf("void
    ");
    }
    
    void foo_int(int c) {
        printf("int: %d
    ", c);
    }
    
    void foo_char(char c) {
        printf("char: %c
    ", c);
    }
    
    void foo_double(double c) {
        printf("double: %f
    ", c);
    }
    
    void foo_double_int(double c, int d) {
        printf("double: %f, int: %d
    ", c, d);
    }
    
    #define foo(...)                                            
    SELECT(__VA_ARGS__)(__VA_ARGS__)
    
    #define CONCAT(X, Y) CONCAT_(X, Y)
    #define CONCAT_(X, Y) X ## Y
    
    #define SELECT(...)                                         
    CONCAT(SELECT_, NARG(__VA_ARGS__))(__VA_ARGS__)
    
    #define SELECT_0()                                          
    foo_void
    
    #define SELECT_1(_1) _Generic((_1),                         
        int: foo_int,                                           
        char: foo_char,                                         
        double: foo_double                                      
    )
    
    #define SELECT_2(_1, _2) _Generic((_1),                     
        double: _Generic((_2),                                  
            int: foo_double_int                                 
        )                                                       
    )
    
    #define ARGN(...) ARGN_(__VA_ARGS__)
    #define ARGN_(_0, _1, _2, /*...*/ N, ...) N
    
    #define NARG(...)                                           
    ARGN(__VA_ARGS__ COMMA(__VA_ARGS__) 3, 2, 1, 0)
    #define HAS_COMMA(...)                                      
    ARGN(__VA_ARGS__, 1, 1, 0)
    
    #define SET_COMMA(...) ,
    
    #define COMMA(...) SELECT_COMMA(                            
        HAS_COMMA(__VA_ARGS__),                                 
        HAS_COMMA(__VA_ARGS__ ()),                              
        HAS_COMMA(SET_COMMA __VA_ARGS__),                       
        HAS_COMMA(SET_COMMA __VA_ARGS__ ())                     
    )
    
    #define SELECT_COMMA(_0, _1, _2, _3)                        
    SELECT_COMMA_(_0, _1, _2, _3)
    #define SELECT_COMMA_(_0, _1, _2, _3)                       
    COMMA_ ## _0 ## _1 ## _2 ## _3
    
    #define COMMA_0000 ,
    #define COMMA_0001
    #define COMMA_0010 ,
    #define COMMA_0011 ,
    #define COMMA_0100 ,
    #define COMMA_0101 ,
    #define COMMA_0110 ,
    #define COMMA_0111 ,
    #define COMMA_1000 ,
    #define COMMA_1001 ,
    #define COMMA_1010 ,
    #define COMMA_1011 ,
    #define COMMA_1100 ,
    #define COMMA_1101 ,
    #define COMMA_1110 ,
    #define COMMA_1111 ,
    
    int main(int argc, char** argv)
    {
        foo();
        foo(7);
        foo(10.12);
        foo(12.10, 7);
        foo((char)'s');
    
        return 0;
    } 

    {

             代码脉络可以详细参照下面 1和 2 讨论.  思索大师的思维 ~ 

      1. https://stackoverflow.com/questions/479207/how-to-achieve-function-overloading-in-c?rq=1

      2. https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/

    }

    对于上面 put.c 演示的 COMMA 宏, 我们用下面一段 demo (define.c)来简单拆解其中一部分思路

    #include <stdio.h>
    
    // https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/
    
    #define _ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) _16
    #define HAS_COMMA(...) _ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
    
    //
    // _TRIGGER_PARENTHESIS_ __VA_ARGS__ (/* empty */)
    //
    #define _TRIGGER_PARENTHESIS_(...) ,
    
    #define HAS_COMMA_EMPTY(...) HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__(/* empty */))
    
    int main(int argc, char * argv[]) {
        printf("%d
    ", HAS_COMMA());
        printf("%d
    ", HAS_COMMA(1));
        printf("%d
    ", HAS_COMMA(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
        printf("%d
    ", HAS_COMMA(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16));
        printf("%d
    ", HAS_COMMA(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17));
    
        printf("%d
    ", HAS_COMMA(,));
        printf("%d
    ", HAS_COMMA_EMPTY());
        return 0;
    }

     

    细细品味推荐的链接. 专业没那么简单 ~ 

    后记 - 简单并不简单

      下次再见, 有问题欢迎沟通交流指正 ~ 祝好运 

      音乐 : 约在春天相见 

  • 相关阅读:
    MSMQ, WCF and IIS: Getting them to play nice (Part 2)[转]
    c#通用函数[转]
    MSMQ, WCF and IIS: Getting them to play nice (Part 1)[转]
    Building a Pub/Sub Message Bus with Wcf,Msmq,IIS
    关于virtual,new,override用法详解
    wcf服务代理层添加wcf服务异步代理
    HttpModule教程
    创造和把握职位升迁的10条规则
    wcf服务代理层添加wcf服务异步代理
    windows server 2008下IIS设置问题
  • 原文地址:https://www.cnblogs.com/life2refuel/p/12330462.html
Copyright © 2011-2022 走看看