在 C/C++ 预处理器中获取宏参数的不同部分

Get different parts of a macro argument in C/C++ preprocessor

我们知道在宏中,我们可以传递任意的东西,例如

#define A(x) void func(x)
#define B(x) func(x)
// to define a function
A(int x) {...}
// to call a function
B(1);

你可能会看到这两个宏的参数完全不同。 我的问题是,对于第一种情况,是否有解决方案来获取宏参数的不同部分:

#define A(x) void func(x) { PART1(x) a = 1; std::cout << (a+PART2(x)); }
A(int x)
// will expand to:
// void func(int x) { int a = 1; std::cout << (a+x); }
func(1);
// outputs 2

是否可以实现 PART1 和 PART2?

是否可以实现PART1和PART2?

是的……有点。 AFAIK 挑选和丢弃由空格分隔的参数片段的唯一方法是对一个部分应用模式匹配,这应该是众所周知的并且是一个标识符。为了适合你的例子,它是这样工作的:

#define GLUEI(A,B) A ## B
#define GLUE(A,B) GLUEI(A,B)
#define SECONDI(_,X,...) X
#define SECOND(...) SECONDI(__VA_ARGS__)
#define PART1(A) SECOND(GLUE(EXTRACTER_,A),~)
#define PART2(A) SECOND(GLUE(SHIFTER_,A),~)
#define SHIFTER_int   ,
#define EXTRACTER_int , int ,

#define A(x) void func(x) { PART1(x) a = 1; std::cout << (a+PART2(x)); }
A(int x)

SECOND 为您提供第二个参数。 EXTRACTOR_foo 的工作是使 foo 单独成为第二个参数。 SHIFTER_foo 的工作是消耗 foo,发出一个逗号,然后让其余的成为第​​二个参数。 SECOND 选择此参数并丢弃匹配器产生的垃圾。