C++ preprocessor __VA_ARGS__ number of arguments

后端 未结 12 2119
一向
一向 2020-11-22 08:03

Simple question for which I could not find answer on the net. In variadic argument macros, how to find the number of arguments? I am okay with boost preprocessor, if it has

12条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-22 08:28

    this works with 0 arguments with gcc/llvm. [links are dumb]

    /*
     * we need a comma at the start for ##_VA_ARGS__ to consume then
     * the arguments are pushed out in such a way that 'cnt' ends up with
     * the right count.  
     */
    #define COUNT_ARGS(...) COUNT_ARGS_(,##__VA_ARGS__,6,5,4,3,2,1,0)
    #define COUNT_ARGS_(z,a,b,c,d,e,f,cnt,...) cnt
    
    #define C_ASSERT(test) \
        switch(0) {\
          case 0:\
          case test:;\
        }
    
    int main() {
       C_ASSERT(0 ==  COUNT_ARGS());
       C_ASSERT(1 ==  COUNT_ARGS(a));
       C_ASSERT(2 ==  COUNT_ARGS(a,b));
       C_ASSERT(3 ==  COUNT_ARGS(a,b,c));
       C_ASSERT(4 ==  COUNT_ARGS(a,b,c,d));
       C_ASSERT(5 ==  COUNT_ARGS(a,b,c,d,e));
       C_ASSERT(6 ==  COUNT_ARGS(a,b,c,d,e,f));
       return 0;
    }
    

    Visual Studio seems to be ignoring the ## operator used to consume the empty argument. You can probably get around that with something like

    #define CNT_ COUNT_ARGS
    #define PASTE(x,y) PASTE_(x,y)
    #define PASTE_(x,y) x ## y
    #define CNT(...) PASTE(ARGVS,PASTE(CNT_(__VA_ARGS__),CNT_(1,##__VA_ARGS__)))
    //you know its 0 if its 11 or 01
    #define ARGVS11 0
    #define ARGVS01 0
    #define ARGVS12 1
    #define ARGVS23 2
    #define ARGVS34 3
    

提交回复
热议问题