C预处理器中的功能绑定操作

时间:2012-04-20 22:55:47

标签: c++ c bind c-preprocessor

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

#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 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分: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

您可以尝试定义更多宏以适当地生成close paren,但可能有更好的解决方案。

答案 2 :(得分:1)

我不确定我是否完全理解您希望实现哪种功能,但以下适合您的示例:

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

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

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

#define MULTIPLY_2(X) multiply2(X)
#define POW_2(X) pow2(X)

答案 3 :(得分: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)
)

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

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

除了C预处理器强加的略微奇怪的语法之外,该语言基本上是一个相当简单的Lisp / ML混合,支持许多常见的功能习语。