使用(高阶)宏可以做多少事情?
将宏名称作为其他宏的参数来模拟高阶函数是否“安全”?
即我应该注意哪里才不会搬起石头砸自己的脚?
以下是一些片段:
#define foreach_even(ii, instr) for(int ii = 0; ii < 100; ii += 2) { instr; }
#define foreach_odd(ii, instr) for(int ii = 1; ii < 100; ii += 2) { instr; }
#define sum(foreach_loop, accu) \
foreach_loop(ii, {accu += ii});
int acc = 0;
sum(foreach_even, acc);
sum(foreach_odd, acc);
部分应用怎么样,我可以这样做吗? :
#define foreach(ii, start, end, step, instr) \
for(int ii = start; ii < end; ii += step) { instr; }
#define foreach_even(ii, instr) foreach(ii, 0, 100, instr)
#define foreach_odd(ii, instr) foreach(ii, 1, 100, instr)
#define sum(foreach_loop, accu) \
foreach_loop(ii, {accu += ii});
int acc = 0;
sum(foreach_even, acc);
sum(foreach_odd, acc);
我可以在宏中定义宏吗?
#define apply_first(new_macro, macro, arg) #define new_macro(x) macro(arg,x)
Is it "safe" to give macros names as arguments to other macros to simulate higher order functions?
I.e. where should I look to not shoot myself in the foot?
Here are some snippets:
#define foreach_even(ii, instr) for(int ii = 0; ii < 100; ii += 2) { instr; }
#define foreach_odd(ii, instr) for(int ii = 1; ii < 100; ii += 2) { instr; }
#define sum(foreach_loop, accu) \
foreach_loop(ii, {accu += ii});
int acc = 0;
sum(foreach_even, acc);
sum(foreach_odd, acc);
What about partial application, can I do that? :
#define foreach(ii, start, end, step, instr) \
for(int ii = start; ii < end; ii += step) { instr; }
#define foreach_even(ii, instr) foreach(ii, 0, 100, instr)
#define foreach_odd(ii, instr) foreach(ii, 1, 100, instr)
#define sum(foreach_loop, accu) \
foreach_loop(ii, {accu += ii});
int acc = 0;
sum(foreach_even, acc);
sum(foreach_odd, acc);
And can I define a macro inside a macro?
#define apply_first(new_macro, macro, arg) #define new_macro(x) macro(arg,x)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您想尽可能多地使用预处理器,您可能需要尝试 boost.preprocessor。
但请注意,这样做不安全。 例如,在使用预处理器时,逗号会导致大量问题。 不要忘记预处理器不理解(或者甚至尝试理解)它们生成的任何代码。
我的基本建议是“不要这样做”,或者“尽可能谨慎地做”。
If you're into using preprocessor as much as possible, you may want to try boost.preprocessor.
But be aware that it is not safe to do so. Commas, for instance, cause a great number of problems when using preprocessors. Don't forget that preprocessors do not understand (or even try to understand) any of the code they are generating.
My basic advice is "don't do it", or "do it as cautiously as possible".
我完全在 c 预处理器中实现了一个烂的小单元测试框架。 几十个宏,很多宏是另一个宏类型的参数。
从最佳实践的意义上来说,这种事情不是“安全”的。 有一些微妙且非常有力的方法会搬起石头砸自己的脚。 单元测试项目是一个失控的玩具。
不知道是否可以嵌套宏定义。 我对此表示怀疑,但我会尝试一下...gcc 不喜欢它,并回应
自插件:如果您有兴趣,可以在 https://sourceforge.net/projects/dut/
I've implemented a rotten little unit testing framework entirely in c-preprocessor. Several dozen macro, lots of macro is an argument to another macro type stuff.
This kind of thing is not "safe" in a best-practices sense of the word. There are subtle and very powerful ways to shoot yourself in the foot. The unit testing project is a toy that got out of hand.
Don't know if you can nest macro definitions. I doubt it, but I'll go try...gcc doesn't like it, and responds with
Self plug: If you're interested the unit testing framework can be found at https://sourceforge.net/projects/dut/