C预处理器中的嵌套宏迭代

6

使用C预处理器,您可以拥有某种类型的高阶宏。就像这样:

#define ABC(f) f(a) f(b) f(c)
#define XY(f) f(x) f(y)

#define CODE(x) foo_ ## x
ABC(CODE)
#undef CODE

#define CODE(x) bar_ ## x
XY(CODE)
#undef CODE

输出结果为:
 foo_a foo_b foo_c
 bar_x bar_y

有什么技巧可以嵌套此类迭代,执行以下操作?
#define CODE(x) foo_ ## x
NEST(ABC, XY, CODE)
#undef CODE

因此,输出结果将会是:
foo_ax foo_ay foo_bx foo_by foo_cx foo_cy

特别是,我希望ABCXY的定义相互独立,这样我就可以单独使用ABC,或者甚至做类似于这样的事情:

#define CODE(x) foo_ ## x
NEST(XY, KLMN, ABC, CODE)
#undef CODE

记录一下,这里是解决方案:
#include <boost/preprocessor/seq.hpp>

#define ABC (a) (b) (c)
#define XY (x) (y)

#define CODE(r, prod) BOOST_PP_CAT(foo_, BOOST_PP_SEQ_CAT(prod))
BOOST_PP_SEQ_FOR_EACH_PRODUCT(CODE, (ABC) (XY))

产生:

foo_ax foo_ay foo_bx foo_by foo_cx foo_cy

1
从经验来看,我可以告诉你,每当你深入使用宏进行元编程时,你几乎肯定会创建一个糟糕的程序设计,并且几乎肯定不是解决问题的正确方法。 "X宏"及其各种衍生品应被视为最后的选择。你真正想要解决的问题是什么? - Lundin
1个回答

3

Boost 预处理器库提供了几个可以立即完成此操作的宏。

BOOST_PP_SEQ_FOR_EACH_PRODUCT将遍历两个或多个列表的笛卡尔积,这些列表以(x) (y) (z)的形式进行编码(在该库中被称为序列)。

BOOST_PP_LIST_FOR_EACH_PRODUCT将对编码为(x, (y, (z, NIL)))的列表执行相同的操作。

X 宏迭代转换为这样的“序列”非常简单:

#define LIST_TO_SEQ(X) (X)
ABC(LIST_TO_SEQ)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接