[C/C++奇技淫巧] 变长宏参数的个数

备忘一个宏的奇技淫巧,类似打印日志,RPC封装等无法使用C++0x变长模板参数的情况下,是个不错的选择

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define ARG_COUNT_P1_(\
  _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) \
  N

#define ARG_COUNT_P2_ \
  9, 8, 7, 6, 5, 4, 3, 2, 1, 0

#define ARG_COUNT_(...) \
  ARG_COUNT_P1_(__VA_ARGS__)

#define ARG_COUNT(...) \
  ARG_COUNT_(_, ##__VA_ARGS__, ARG_COUNT_P2_)

#define M_CAT(a, b) M_CAT_(a, b)
#define M_CAT_(a, b) a##b

#define VA_F(...) \
  M_CAT(func, ARG_COUNT(__VA_ARGS__)) (__VA_ARGS__)

#define func(a)   fprintf(stdout, "arg:%ld\t", a);
#define func0()   fprintf(stdout, "func end\n\n");
#define func1(a)  func(a); func0();
#define func2(a, ...) func(a); func1(__VA_ARGS__);
#define func3(a, ...) func(a); func2(__VA_ARGS__);
#define func4(a, ...) func(a); func3(__VA_ARGS__);
#define func5(a, ...) func(a); func4(__VA_ARGS__);
#define func6(a, ...) func(a); func5(__VA_ARGS__);
#define func7(a, ...) func(a); func6(__VA_ARGS__);
#define func8(a, ...) func(a); func7(__VA_ARGS__);
#define func9(a, ...) func(a); func8(__VA_ARGS__);
#define func10(a, ...) func(a); func9(__VA_ARGS__);

int main(int argc, char **argv)
{
  fprintf(stdout, "arg=%ld\n", ARG_COUNT());
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4,5));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4,5,6));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4,5,6,7));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4,5,6,7,8));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4,5,6,7,8,9));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4,5,6,7,8,9,10));
  fprintf(stdout, "arg=%ld\n", ARG_COUNT(1,2,3,4,5,6,7,8,9,10,11));

  VA_F();
  VA_F(1);
  VA_F(1,2);
  VA_F(1,2,3);
  VA_F(1,2,3,4);
  VA_F(1,2,3,4,5);
  VA_F(1,2,3,4,5,6);
  VA_F(1,2,3,4,5,6,7);
  VA_F(1,2,3,4,5,6,7,8);
  VA_F(1,2,3,4,5,6,7,8,9);
  VA_F(1,2,3,4,5,6,7,8,9,10);
  //VA_F(1,2,3,4,5,6,7,8,9,10,11);
}

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注