开发者

C++ Macro Arithmetric

开发者 https://www.devze.com 2022-12-23 15:59 出处:网络
I have to do with Macros (it\'s macros calling macros; so templates are out of the question). Here\'s what I want:

I have to do with Macros (it's macros calling macros; so templates are out of the question).

Here's what I want:

foo(3, a, b1, c1) --> foo1(a, b1, c1);
foo(5, a, b1, c1, b2, c2) -> foo2(a, b1, c1, b2, c2);
foo(7, a, b1, c1, b2, c2, b3开发者_运维技巧, c3) -> foo3(a, b1, c1, b2, c2, b3, c3);

So basically, what I want is to be able to execute the "function" n -> (n-1)/2 at macro expansion time. Is this possible?

[PS, if you dislike my questions; I support your right to downvote; my worst question so far is only -17, so maybe we can break that record; however, please let me know why my question is technically invalid.]

EDIT:

Foo takes a variable # of arguments, of the form:

foo(N, a1, b1, a2, b2, ... a_N, b_N) -> foo##N(a1, b1, a2, b2, ... a_N, b_N);

EDIT:

To all the closers. This is a very different question. The former is about "how do I count the # of arguments in a Macro." (to which there was a good response on the mailing list).

This question is a matter of: given I've counted the # of arguments, how do I dispatch on it?


I haven't tested this, but should work:

#define SUBSTFOO3( a, b1, c1 ) foo1(a, b1, c1)
#define SUBSTFOO5( a, b1, c1, b2, c2 ) foo2(a, b1, c1, b2, c2)
/* ad nauseam */

#define foo( N, ... ) SUBSTFOO ## N ( __VA_ARGS__ )

This might also work:

#define SUBSTFOO3 foo1 /* no arguments needed */
#define SUBSTFOO5 foo2 /* "( __VA_ARGS__)" already the correct substitution */

#define foo( N, ... ) SUBSTFOO ## N ( __VA_ARGS__ )


I'm not sure I understand your question, but it reminds me of this trickery I saw in the GCC source. Maybe you'll spot something applicable.

#if GCC_VERSION >= 3000 || __STDC_VERSION__ >= 199901L
/* Use preprocessor trickery to map "build" to "buildN" where N is the
   expected number of arguments.  This is used for both efficiency (no
   varargs), and checking (verifying number of passed arguments).  */
#define build(code, ...) \
  _buildN1(build, _buildC1(__VA_ARGS__))(code, __VA_ARGS__)
#define _buildN1(BASE, X)   _buildN2(BASE, X)
#define _buildN2(BASE, X)   BASE##X
#define _buildC1(...)       _buildC2(__VA_ARGS__,9,8,7,6,5,4,3,2,1,0,0)
#define _buildC2(x,a1,a2,a3,a4,a5,a6,a7,a8,a9,c,...) c
#endif
0

精彩评论

暂无评论...
验证码 换一张
取 消