迭代变量宏观参数

我正在以编程方式生成一堆仿函数,以保持生成的代码更具可读性我试图想出一个宏将扩展以下行,

SET_STATE(FunctorA,a,b); ref a; ref b; FunctorA(ref a, ref b){ this->a = a; this->b = b; } 

基本上它将扩展到第一个参数构造函数。 可变参数部分是构造函数的参数数量。 是否有可能在宏内部循环并在预处理期间生成此代码,即使它对这个特定情况没有意义但我有一些具有20个左右变量的仿函数,他们可以访问它将清理我生成的代码很多。

所有参数都是相同的类型,只有名称会有所不同。

使用此链接http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/中的技巧来计算参数的数量并使用一些非常丑陋的宏我可以生成您想要的输出。

我使用gcc (gcc -E test.cpp)测试它, 可以工作, 它不可移植

码:

 #define VA_NARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) #define SET_STATEGENERATE(name, count, ...) \ dec ## count (__VA_ARGS__) \ name(ref ## count (__VA_ARGS__)) { \ con ## count (__VA_ARGS__) \ } #define SET_STATEP(name, count, ...) SET_STATEGENERATE(name, count, __VA_ARGS__) #define SET_STATE(name, ...) SET_STATEP(name, VA_NARGS(__VA_ARGS__), __VA_ARGS__) /* args */ #define dec1(a) ref a; #define dec2(a,b) dec1(a) ref b; #define dec3(a,b,c) dec2(a, b) ref c; #define dec4(a,b,c,d) dec3(a,b,c) ref d; #define dec5(a,b,c,d,e) dec4(a,b,c,d) ref e; #define dec6(a,b,c,d,e,f) dec5(a,b,c,d,e) ref f; #define dec7(a,b,c,d,e,f,g) dec6(a,b,c,d,e,f)ref g; #define dec8(a,b,c,d,e,f,g,h) dec7(a,b,c,d,e,f,g) ref h; #define ref1(a) ref a #define ref2(a,b) ref1(a), ref b #define ref3(a,b,c) ref2(a,b), ref c #define ref4(a,b,c,d) ref3(a,b,c), ref d #define ref5(a,b,c,d,e) ref4(a,b,c,d), ref e #define ref6(a,b,c,d,e,f) ref5(a,b,c,d,e), ref f #define ref7(a,b,c,d,e,f,g) ref6(a,b,c,d,e,f), ref g #define ref8(a,b,c,d,e,f,g, h) ref7(a,b,c,d,e,f,g), ref h #define con1(a) this->a = a; #define con2(a,b) con1(a) this->b = b; #define con3(a,b,c) con2(a,b) this->c = c; #define con4(a,b,c,d) con3(a,b,c) this->d = d; #define con5(a,b,c,d,e) con4(a,b,c,d) this->e = e; #define con6(a,b,c,d,e,f) con5(a,b,c,d,e) this->f = f; #define con7(a,b,c,d,e,f,g) con6(a,b,c,d,e,f) this->g = g; #define con8(a,b,c,d,e,f,g,h) con7(a,b,c,d,e,f,g) this->h = h; 

以下是:

 /* 2 args */ SET_STATE(FunctorAA, foo, bar) /* 3 args */ SET_STATE(FunctorBB, foo, bar, baz) /* 4 args */ SET_STATE(FunctorCC, foo, bar, baz, qux) 

将产生:

 ref foo; ref bar; FunctorAA(ref foo, ref bar) { this->foo = foo; this->bar = bar; } ref foo; ref bar; ref baz; FunctorBB(ref foo, ref bar, ref baz) { this->foo = foo; this->bar = bar; this->baz = baz; } ref foo; ref bar; ref baz; ref qux; FunctorCC(ref foo, ref bar, ref baz, ref qux) { this->foo = foo; this->bar = bar; this->baz = baz; this->qux = qux; } 

注意:您可以按照明显的模式继续参数的数量。

如果允许boost::preprocessorSEQ表示( (a)(b)... ),则以下代码可能符合以下目的:

 #include  #include  #include  #define DEF_MEMBER( r, data, elem ) ref elem; #define DEF_PARAM( r, data, i, elem ) BOOST_PP_COMMA_IF( i ) ref elem #define DEF_ASSIGN( r, data, elem ) this->elem = elem; #define SET_STATE( f, members ) \ BOOST_PP_SEQ_FOR_EACH( DEF_MEMBER,, members ) \ f( BOOST_PP_SEQ_FOR_EACH_I( DEF_PARAM,, members ) ) { \ BOOST_PP_SEQ_FOR_EACH( DEF_ASSIGN,, members ) \ } SET_STATE(FunctorA,(a)(b)) 

上面的代码扩展为

 ref a; ref b; FunctorA( ref a , ref b ) { this->a = a; this->b = b; } 

在我的环境中。