C++ 如何用宏删除圆括号?
宏参数中不允许使用逗号,因为它将被视为多个参数,并且预处理将出错。但是,我们可以将参数插入括号,让预处理器将其作为一个参数处理。是否有宏或其他技术可以删除括号 例如,如果我定义一个宏,如C++ 如何用宏删除圆括号?,c++,macros,c-preprocessor,C++,Macros,C Preprocessor,宏参数中不允许使用逗号,因为它将被视为多个参数,并且预处理将出错。但是,我们可以将参数插入括号,让预处理器将其作为一个参数处理。是否有宏或其他技术可以删除括号 例如,如果我定义一个宏,如 #define MY_MACRO(a, b) ... 像这样使用它 MY_MACRO( A<int, double>, text ); MY_MACRO( (A<int, double>), text) MY_宏(A,文本); 这将是错误的。像这样使用它 MY_MACRO(
#define MY_MACRO(a, b) ...
像这样使用它
MY_MACRO( A<int, double>, text );
MY_MACRO( (A<int, double>), text)
MY_宏(A,文本);
这将是错误的。像这样使用它
MY_MACRO( A<int, double>, text );
MY_MACRO( (A<int, double>), text)
MY_宏((A),文本)
使用宏或技术删除括号就可以了。Boost仅为类型而非一般情况提供Boost\u IDENTITY\u TYPE
宏
#define ESC(...) __VA_ARGS__
然后
MY_宏(ESC(A),文本);
可能会做你想做的。一个简单的方法就是使用可变宏:
#define MY_MACRO(a, b...) ...
然后你可以像这样使用它:
MY_MACRO(text, A<int, double>)
MY_宏(文本,A)
第二个参数中的逗号仍然被解释为参数分隔符(这意味着宏实际上是用三个参数调用的),但它在宏内部被展开,使行为相同。但是,变量参数必须是宏中的最后一个。此宏技巧类似于Yakk的解决方案,但不需要显式地将另一个宏作为参数传递
#include <stdio.h>
#define _Args(...) __VA_ARGS__
#define STRIP_PARENS(X) X
#define PASS_PARAMETERS(X) STRIP_PARENS( _Args X )
int main()
{
printf("without macro %d %d %d %d %d %d\n", (5,6,7,8,9,10) ); // This actually compiles, but it's WRONG
printf("with macro %d %d %d %d %d %d\n", PASS_PARAMETERS((5,6,7,8,9,10)) ); //Parameter "pack" enclosed in parenthesis
return 0;
}
#包括
#定义_参数(…)_参数__
#定义条带参数(X)X
#定义过程参数(X)带参数(_参数X)
int main()
{
printf(“没有宏%d%d%d%d%d%d\n”,(5,6,7,8,9,10));//这实际上是编译的,但它是错误的
printf(“使用宏%d%d%d%d%d%d\n”,传递_参数((5,6,7,8,9,10));//括号中的参数“pack”
返回0;
}
当然,您可以通过将PASS_PARAMETERS宏转换为可变宏并在多个参数包中进行传递来获得创造性。仅可能删除括号:
如果需要去除一层括号,但只有在有括号要去除时,这组较长的宏才起作用:
#define DEPAREN(X) ESC(ISH X)
#define ISH(...) ISH __VA_ARGS__
#define ESC(...) ESC_(__VA_ARGS__)
#define ESC_(...) VAN ## __VA_ARGS__
#define VANISH
如果要对不同的数据类型集使用MY\u宏
,则可能需要此选项:
#define MY_MACRO(a, b) DEPAREN(a), b
MY_MACRO( ({x, y, z}), text )
//> {x,y,z}, text
MY_MACRO( singlearg, text )
//> singlearg, text
工作原理:
我们从DEPAREN(X)ESC(ISH X)
开始。如果X有括号,我们得到ESC(ISH(X))
。如果X没有括号,我们得到ESC(ISH X)
然后我们将ESC(…)
展开为ESC_wu(wu VA_wuargs)
,这将展开内部
ISH(…)
变成ISH\uu VA\u ARGS\uuuu
,从X中去掉一层括号。现在,不管X最初是否有括号,我们都有ESC_uu(ISH X)
我们现在需要摆脱ISH
。但是,因为我们已经定义了ISH(…)
,所以不能将其定义为#define ISH
。这就是为什么我们将它与另一个标记(VAN
)连接起来,以获得消失X
invision
被定义为
,因此我们最后只剩下X
,没有括号。一个解决方法-typedef A IA;MY_宏(IA,文本)代码>typedef比所有的预处理器黑客都要优雅。好简单!或者,ESC可以进入MY_宏,例如定义MY_宏(a,b)ESC a(b)
MY_宏((a),文本)代码>-->A(文本)代码>(变量声明)这是一个很好的答案。需要了解的重要部分是,\u Args
宏不会将X
包装在()
中。这样,它自然地连接和解析括号。