我们知道,在宏中,我们可以传递任意的东西,例如
#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 选择这个参数并丢弃匹配器产生的垃圾。
关于c++ - 在 C/C++ 预处理器中获取宏参数的不同部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32002113/