问题描述
|
我正在编写一些Boost.Preprocessor元程序,但存在以下问题。请考虑以下宏(这是为了简化说明问题):
#define IteraTION_IMPL(p1,p2,p3,p4) ((p1),(p2),(p3),(p4))
#define IteraTION(args) IteraTION_IMPL(hello,args(),world)
#define ARGS() a,b
IteraTION(ARGS)
预处理后的输出是这样的:
((hello),(a,b),(world),())
这表明“ 2”没有分成多个参数。根据我对标准的理解,宏的参数在粘贴到替换列表之前已被完全扩展。因此,我期望以下扩展顺序:
IteraTION(ARGS)
IteraTION_IMPL(hello,ARGS(),world)
IteraTION_IMPL(hello,a,b,world)
((hello),(a),(b),(world))
那是我想要的结果。如何在不修改ѭ4和调用本身的情况下实现它?
编辑:如果不可能(我猜是这样),请根据C或C ++的任何标准进行解释。
解决方法
我认为如果遇到
ITERATION(ARGS)
,则需要ITERATION_IMPL(hello,args(),world)
,将args
替换为ARGS
,然后重新扫描。 ITERATION_IMPL(hello,ARGS(),world)
是ITERATION_IMPL
的调用。因此,它取((p1),(p2),(p3),(p4))
,并将and12ѭ替换为ARGS()
(以及其他参数)。然后重新扫描并解析为((hello),(a,b),(world),())
。我不知道为什么它会在您的情况下调用带有3个参数的4参数宏。
你可以做
#define EVAL(X) X
#define ITERATION(args) ITERATION_IMPL EVAL((hello,world))
这将花费X
,替换为(hello,world)
,然后重新扫描,从而使ARGS()
替换为ѭ19replaced。生成的令牌字符串ѭ20then会达到您的预期。
编辑:测试与海湾合作委员会:)
编辑:我注意到您想要字符串((hello),(a),(b),(world))
,但是我的答案却产生了字符串ITERATION_IMPL (hello,a,b,world)
。我认为这是因为当调用ITERATION
后重新扫描时,它将it24ѭ替换为ITERATION_IMPL (hello,wold)
。然后它将需要再次扫描以注意它现在可以使用这些参数调用ITERATION_IMPL
。所以ITERATION
应该是
#define ITERATION(args) EVAL(ITERATION_IMPL EVAL((hello,world)))
当外部EVAL
的X
替换为ѭ31substituted时,它将重新扫描并产生ITERATION_IMPL (hello,world)
来调用EVAL
。然后它再次重新扫描以查找ITERATION
,并产生您真正想要的序列。