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

时间:2012-02-23 16:02:43

标签: c++ macros

考虑一个简单的宏:

#define ECHO(x) x

ECHO(foo(1, 2))

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

foo(1, 2)

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

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

ECHO(template<int, bool>)

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

无论如何在宏中使用这样的模板吗?

3 个答案:

答案 0 :(得分:11)

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

有点痛苦,但它确实有效。

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

ECHO((a, b))

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

答案 1 :(得分:5)

可变参数宏可能会有所帮助:

#define ECHO(x...) x

ECHO(foo(1, 2))
ECHO(template<int, bool>)

答案 2 :(得分:1)

如果允许在项目中使用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部分将如下所示:


declarations.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 section标记将它的用法包装在注释中,它实际上可能比为小用法手动编写代码更糟糕。当你需要声明大枚举或许多不可避免的样板代码时,它真的得到回报