您可以像这样添加到宏中以获得某种可维护的列表:
#define GEN_X(f) REP_INT(3, f)
#define GEN_Y(f, x) f(x, real) f(x, bool) f(x, index)
#define GEN_Z(f, x, y) f(x, y, 0) f(x, y, 1)
// GEN_F3 = generate functions with at least 3 arguments
#define GEN_F3(x, y, z) template bool match_any<x, y, z>();
#define GEN_F2(x, y) template bool match_any<y<x>>(); GEN_Z(GEN_F3, x, y)
#define GEN_F1(x) template bool match_any<x>(); GEN_Y(GEN_F2, x)
GEN_X(GEN_F1)
demo http://coliru.stacked-crooked.com/a/785dfa5889d1e931
我们将变量生成器分开,然后将它们链接在一起以获得所有排列:您的宏生成x
的,通过管道输送到GEN_F1
,它处理单参数情况并通过管道传输这些x
值对y
- 发电机等。
请注意,尽管我们已经使源代码可线性维护,但我们无法避免可执行文件大小的指数级增长。
为了解决您的扩展问题,如果您希望能够处理两个参数的数字的任何排列,例如 x={1,2,3}, y={1,2,3,4},直观上您可能想要像这样调整:
#define GEN_X(f) REP_INT(3, f)
#define GEN_Y(f, x) REP_INT(4, f)
这几乎可行,但宏扩展阻止在一次递归扩展中再次使用相同的 REP_INT_* 宏(至少以我所做的方式)。
一种解决方法是有两个REP_INT
列表(其中至少一个需要处理可变输入,将数字附加到末尾)。宏可以相同,只是名称需要不同才能继续扩展。
然后我们可以像这样解决扩展问题:
#define GEN_X(f) REP1_INT_3(f)
#define GEN_Y(f, x) REP2_INT_4(f, x)
#define GEN_F2(x, y) template bool match_any<x, y>();
#define GEN_F1(x) GEN_Y(GEN_F2, x)
GEN_X(GEN_F1)
demo http://coliru.stacked-crooked.com/a/3ad685e44d95b927