C预处理程序递归宏 [英] C-preprocessor recursive macro

查看:76
本文介绍了C预处理程序递归宏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#define PP_ARG0_(arg0, ...) arg0
#define PP_REST_(arg0, ...) __VA_ARGS__
#define PP_ARG0(args) PP_ARG0_ args
#define PP_REST(args) PP_REST_ args

#define FUNCTION(name) void name();
#define FUNCTION_TABLE(...)                   \
    FUNCTION(PP_ARG0((__VA_ARGS__)))          \
    FUNCTION_TABLE(PP_REST((__VA_ARGS__)))    \

测试代码:

FUNCTION_TABLE(f1, f2,f3,testA,testB,testC);

显然,由于递归扩展,它只会声明 void f1(); ,其余的将不会扩展:

Obviously, because of recursive expansion it will only declare void f1(); and the rest won't be expanded:

void f1(); FUNCTION_TABLE(f2,f3,testA,testB,testC);

在这种情况下,我可以使用哪种技巧来实现递归扩展?问题是我需要支持许多参数(最多100个),而且我绝对不能使用boost。

What kind of trick can I use to achieve recursive expansion in this case? The problem is that I need to support MANY arguments (up 100) and I absolutely cannot use boost.

推荐答案

以下是答案

#define _PP_0(_1, ...) _1            // (a,b,c,d) => a
#define _PP_X(_1, ...) (__VA_ARGS__) // (a,b,c,d) => (b,c,d)

//for each a in __VA_ARGS__ do f(a,x) 
//where x is some parameter passed to PP_TRANSFORM
#define PP_TRANSFORM(f,x,...) \
    PP_JOIN(PP_TRANSFORM_,PP_NARG(__VA_ARGS__))(f,x,(__VA_ARGS__))

#define PP_TRANSFORM_0(...)
#define PP_TRANSFORM_1( f,x,a) f(_PP_0 a,x) PP_TRANSFORM_0( f,x,_PP_X a)
#define PP_TRANSFORM_2( f,x,a) f(_PP_0 a,x) PP_TRANSFORM_1( f,x,_PP_X a)
...
#define PP_TRANSFORM_51(f,x,a) f(_PP_0 a,x) PP_TRANSFORM_50( f,x,_PP_X a)
...
#define PP_TRANSFORM_99(f,x,a) f(_PP_0 a,x) PP_TRANSFORM_98(f,x,_PP_X a)
#define PP_TRANSFORM_100(f,x,a)f(_PP_0 a,x) PP_TRANSFORM_99(f,x,_PP_X a)

其中 PP_NARG 是用于计算参数数量和 PP_JOIN 是连接令牌的宏(即 PP_JOIN(a,b)= >> ab )。如果您希望能够处理64个以上的参数,则还需要修补该 PP_NARG

where PP_NARG is the macro that counts number of arguments and PP_JOIN is the macro that joins tokens (that is PP_JOIN(a,b) => ab). You'll also need to patch that PP_NARG if you want to be able to process more than 64 arguments.

现在,回到原来的问题。使用 PP_TRANSFORM 的解决方案是:

Now, back to the original question. Solution using the PP_TRANSFORM is:

#define FUNCTION(name, dummy) void name();
#define FUNCTION_TABLE(...) PP_TRANSFORM(FUNCTION,dummy,__VA_ARGS__)

如果您想要生成c ++实现函数,则可以使用 PP_TRANSFORM 的不透明x参数:

if you want to generate c++ implementation functions then you can use that opaque x parameter of PP_TRANSFORM:

#define FUNCTION_CPP(name, class) void class::name(){}
#define FUNCTION_TABLE_CPP(...) PP_TRANSFORM(FUNCTION_CPP,MyClass,__VA_ARGS__)

所有这些在GCC和MSVC预处理器中均能很好地工作; PP_TRANSFORM_NN不会使用 __ VA_ARGS __ 来避免对GCC和MSVC单独定义100个定义

All this works equally well with GCC and MSVC preprocessors; PP_TRANSFORM_NN doesn't use __VA_ARGS__ to avoid separate implementations of 100 defines for GCC and MSVC

这篇关于C预处理程序递归宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆