在没有括号的宏中使用逗号:如何与模板混合和匹配

Using commas inside a macro without parenthesis: How can I mix and match with a template?

本文关键字:混合      更新时间:2023-10-16

考虑一个简单的宏:

#define ECHO(x) x
ECHO(foo(1, 2))

这产生了我们期望的确切输出:

foo(1, 2)

上面的例子之所以有效,是因为预处理器可以识别与函数调用相邻的括号。

现在考虑一下如果我使用模板而不是函数调用会发生什么:

ECHO(template<int, bool>)

这会导致错误,因为预处理器将template<intbool>解释为宏的两个独立参数。预处理器无法识别作用域的<>

有没有在宏中使用这样的模板?

#define COMMA ,
ECHO(template<int COMMA bool>)

有点痛苦,但它有效。

FWIW,如果参数的语法允许()s,则不需要替换,例如

ECHO((a, b))

将适用于单参数宏,但这并不适用于所有情况(包括您的情况)。

可变宏可能会有所帮助:

#define ECHO(x...) x
ECHO(foo(1, 2))
ECHO(template<int, bool>)

如果您允许在项目中使用Cog,您的代码将变得更可读:

/*[[[cog
# definitions ----
import cog
def AddDeclaration( templateArg , restOfDeclaration ):
    cog.outl(' %s struct %s; ' % (templateArg , restOfDeclaration))
# generation ---
types = ['bool' , 'std::string']
names = ['Foo' , 'Bar']
for index in range(len(names)):
    AddDeclaration( 'template<int, %s>' % types[index] , names[index])
]]]*/
//[[[end]]]

在你对这个文件运行cog之后,你会得到:

/*[[[cog
# definitions ----
import cog
def AddDeclaration( templateArg , restOfDeclaration ):
    cog.outl(' %s struct %s; ' % (templateArg , restOfDeclaration))
# generation ---
types = ['bool' , 'std::string']
names = ['Foo' , 'Bar']
for index in range(len(names)):
    AddDeclaration( 'template<int, %s>' % types[index] , names[index])
]]]*/
template<int, bool> struct Foo; <---------------- generated by Cog!!
template<int, std::string> struct Bar;
//[[[end]]]

你甚至可以在单独的.py文件中移动你的定义,cog部分看起来像:


声明.py

import cog
def AddDeclaration( templateArg , restOfDeclaration ):
    cog.outl(' %s struct %s; ' % (templateArg , restOfDeclaration))

my.h

/*[[[cog
# definitions ----
import declarations
# generation ---
types = ['bool' , 'std::string']
names = ['Foo' , 'Bar']
for index in range(len(names)):
    AddDeclaration( 'template<int, %s>' % types[index] , names[index])
]]]*/
template<int, bool> struct Foo;
template<int, std::string> struct Bar;
//[[[end]]]

使用cog的主要优点是可以完全控制代码生成,使用boost预处理器或类似的东西可以完全避免不可读的混乱。

主要的缺点是,您在项目中添加了一个新的工具依赖项,而且由于您需要用cog部分标记将其用法包装在注释中,这实际上可能比为小的用途手动编写代码更糟糕。当您需要声明大枚举或大量不可避免的样板代码

时,它确实会得到回报