1

我有一个这样的宏(它来自一个实际有用的用例,但我一直在玩简化的案例):

#define MY_MACRO(M)  M(3) M(5) M(7)
#define MULTIPLY_BY_2(A)  (2*A)

然后我可以写

MY_MACRO(MULTIPLY_BY_2)
// -> (2*3) (2*5) (2*7)

凉爽的!我想要的是这样的:

#define MULTIPLY(A,B) (A*B)
MY_MACRO(BIND(MULTIPLY, 2))

得到与上面相同的结果。BIND 可能是什么?我已经尝试了一些技巧,并且可以报告这几乎是可能的(我觉得这很神奇)。但它并不漂亮,也不一般。这能做好吗?(即纯粹在 CPP 中构建一些真正的功能性设施?)绑定一个绑定宏可以做得很好吗?

也许我真正要问的是,您知道的任何预处理器库中是否有这样的工具?我在 Boost 中没有找到类似的东西。

4

4 回答 4

4

对不起,你不能要求宏编程漂亮。

于 2012-04-20T23:02:12.737 回答
2

不平衡的括号可以做一种绑定操作,但是调用语法与普通宏不同。它需要一个额外的近亲。

#define BIND( op, arg ) op ( arg,
#define MULTIPLY( a, b ) ( (a) * (b) )

#define MULTIPLY_BY_2 BIND( MULTIPLY, 2 )

MULTIPLY_BY_2( 5 )) // note two close parens

http://ideone.com/EQvs2

您可以尝试定义更多的宏来适当地生成关闭括号,但可能有更好的解决方案。

于 2012-04-21T08:25:09.560 回答
1

我不确定我是否完全理解您想要实现什么样的功能,但以下内容适合您的示例:

#define MULTIPLY_2(X) (2*(X))
#define POW_2(X) ((X)*(X))
#define BIND(OP, NUM) OP ## _ ## NUM

for MULTIPLY_2& Co 请注意,您总是在参数周围加上括号,以确保它具有您想要的评估顺序。还要注意,一般策略参数可能会被多次评估,如果表达式包含副作用,这可能是一个严重的错误。

最好将您的基本操作作为内联函数并使用宏组合函数调用

#define MULTIPLY_2(X) multiply2(X)
#define POW_2(X) pow2(X)
于 2012-04-21T07:47:05.567 回答
1

其实,是。在Order library中,您可以这样表达上述内容:

#include <order/interpreter.h>

#define ORDER_PP_DEF_8my_mac ORDER_PP_FN( \
8fn(8M, 8seq(8ap(8M, 3), 8ap(8M, 5), 8ap(8M, 7))) )

#define ORDER_PP_DEF_8bind ORDER_PP_FN( \
8fn(8F, 8A, 8fn(8X, 8ap(8F, 8A, 8X)) ) )

#define ORDER_PP_DEF_8multiply ORDER_PP_FN( \
8fn(8L, 8R, 8times(8L, 8R)) )      // (already built-in as 8times)

ORDER_PP (
    8my_mac(8bind(8multiply, 2))   // -> (6)(10)(14)
)

那是手动定义bindand multiply; Order 本身也支持 ML 风格的部分评估,所以你可以写:

ORDER_PP ( 8my_mac(8times(2)) )    // -> (6)(10)(14)

除了由 C 预处理器强加的稍微奇怪的语法之外,该语言基本上是一种相当简单的 Lisp/ML 混合体,支持许多常见的函数式惯用语。

于 2015-05-01T05:22:09.623 回答