我有一个像这样的宏(它来自一个实际有用的用例,但我一直在玩简化案例):
#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中找不到任何类似的东西。
答案 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
您可以尝试定义更多宏以适当地生成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)
)
这是bind
和multiply
的手动定义; Order本身也支持ML风格的部分评估,所以你可以写:
ORDER_PP ( 8my_mac(8times(2)) ) // -> (6)(10)(14)
除了C预处理器强加的略微奇怪的语法之外,该语言基本上是一个相当简单的Lisp / ML混合,支持许多常见的功能习语。