I need to use a variadic macro to expand to multiple variations of a class. Since they need to have different names based on the macro input I can't simply use templates. The problem is that I can't expand the comma (,
) symbol, and my class has functions which take multiple parameters (for which I need to use the comma symbol).
我需要使用可变参数宏来扩展到类的多个变体。由于他们需要根据宏输入使用不同的名称,所以我不能简单地使用模板。问题是我无法扩展逗号(,)符号,并且我的类具有带有多个参数的函数(我需要使用逗号符号)。
boost
provides the BOOST_PP_COMMA()
macro which expands to a comma, but it only works outside of loop constructs. I'm guessing the issue is that BOOST_PP_COMMA()
is expanded once and then treated as a comma, at which point the program breaks.
boost提供了BOOST_PP_COMMA()宏,它扩展为逗号,但它只能在循环结构之外工作。我猜测问题是BOOST_PP_COMMA()被展开一次,然后被视为逗号,此时程序会中断。
To illustrate the problem, suppose I have a macro function which takes a variadic number of parameters and produces a number of commas equal to the number of parameters given to it. The naive solution would be this:
为了说明这个问题,假设我有一个宏函数,它接受可变数量的参数并产生一些等于给定参数数量的逗号。天真的解决方案是这样的:
#define TEST(...)\
BOOST_PP_REPEAT( \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
MACRO, \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
#define MACRO(z, n, data) BOOST_PP_IF(1,BOOST_PP_COMMA(),BOOST_PP_COMMA())\
But this produces a range of errors because the comma is expanded and the macro thinks they're dividing parameters.
但是这会产生一系列错误,因为逗号被扩展并且宏认为它们正在划分参数。
Is there any way around this problem?
有没有解决这个问题的方法?
1 个解决方案
#1
1
Using BOOST_PP_REPEAT
with a macro that can be called with the expected arguments will work fine, and it even prevents the need for BOOST_PP_COMMA
:
将BOOST_PP_REPEAT与可以使用预期参数调用的宏一起使用将正常工作,甚至可以防止需要BOOST_PP_COMMA:
#define PRINT_COMMAS(...)\
BOOST_PP_REPEAT( \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
PRINT_COMMAS_MACRO, \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
#define PRINT_COMMAS_MACRO(z, n, data) ,
看得出来了
To save the extra macro, you can take advantage of the fact that BOOST_PP_ENUM
adds commas between expansions by adding one to the number of repetitions and discarding the macro arguments using BOOST_PP_TUPLE_EAT
:
要保存额外的宏,您可以利用BOOST_PP_ENUM在扩展之间添加逗号这一事实,方法是在重复次数上加1,并使用BOOST_PP_TUPLE_EAT丢弃宏参数:
#define PRINT_COMMAS(...)\
BOOST_PP_ENUM( \
BOOST_PP_INC(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)), \
BOOST_PP_TUPLE_EAT(), \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
看得出来了
I personally think the first is more clear.
我个人认为第一个更清楚。
#1
1
Using BOOST_PP_REPEAT
with a macro that can be called with the expected arguments will work fine, and it even prevents the need for BOOST_PP_COMMA
:
将BOOST_PP_REPEAT与可以使用预期参数调用的宏一起使用将正常工作,甚至可以防止需要BOOST_PP_COMMA:
#define PRINT_COMMAS(...)\
BOOST_PP_REPEAT( \
BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
PRINT_COMMAS_MACRO, \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
#define PRINT_COMMAS_MACRO(z, n, data) ,
看得出来了
To save the extra macro, you can take advantage of the fact that BOOST_PP_ENUM
adds commas between expansions by adding one to the number of repetitions and discarding the macro arguments using BOOST_PP_TUPLE_EAT
:
要保存额外的宏,您可以利用BOOST_PP_ENUM在扩展之间添加逗号这一事实,方法是在重复次数上加1,并使用BOOST_PP_TUPLE_EAT丢弃宏参数:
#define PRINT_COMMAS(...)\
BOOST_PP_ENUM( \
BOOST_PP_INC(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)), \
BOOST_PP_TUPLE_EAT(), \
BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__))
看得出来了
I personally think the first is more clear.
我个人认为第一个更清楚。