每个令牌的可变参数宏扩展 [英] Variadic macro expansion for each token

查看:60
本文介绍了每个令牌的可变参数宏扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个宏,一个简单的宏,仅针对不同类型调用函数 foo

  #define FOO(type)foo _ ## type(); 

一口气,假设我要为多种不同的类型称呼此东西。具体来说;

  foo_int(); 
foo_float();
foo_point2d();

我想使用称为 FOO2

  #define FOO2(args ...)--fill--here 

为了完整起见, FOO2(int,float,point2d)应该扩展到上面的小代码段。



我确定这样的问题已经存在了吗?



我可以确定宏是否可行,以及如何对可变参数宏令牌包中的每个参数执行不同的单独操作?我搜索了其他一些结果,显示了某种 FOR_EACH 宏实现,该实现非常复杂且通用。这就是为什么我决定询问我的特定用例并开始一个新问题。

解决方案

是的,有可能,但是需要多个宏。

  #define MAP1(m,t,...)m(t)
#define MAP2 (m,t,...)m(t); MAP1(m,__ VA_ARGS__)
#定义MAP3(m,t,...)m(t); MAP2(m,__ VA_ARGS__)
// ...根据需要添加更多...
#定义MAP(n,...)MAP ## n(__ VA_ARGS__)

#定义FOO(类型)foo _ ## type()
#定义FOON(n,...)MAP(n,FOO,__VA_ARGS__)

FOON(3,int,float ,double);

上面将产生:

  foo_int(); foo_float(); foo_double(); 

如果您不想将数字指定为参数,请添加以下内容:

  #define FOO1(...)FOON(1,__VA_ARGS__)
#define FOO2(...)FOON(2, __VA_ARGS__)
#定义FOO3(...)FOON(3,__VA_ARGS__)
// ...根据需要添加更多...

现在您可以这样做:

  FOO3(int,浮动,两倍); 






通过更多的工作,您甚至可以具有任何函数名称的宏工作:

  #define MAP1(m,f,t,...)m(f,t )
#定义MAP2(m,f,t,...)m(f,t); MAP1(m,f,__ VA_ARGS__)
#定义MAP3(m,f,t,...)m(f,t); MAP2(m,f,__ VA_ARGS__)
// ...
#define MAP(n,...)MAP ## n(__ VA_ARGS__)

#define CALL( funcname,type)funcname ## _ ## type()
#define CALLN(n,funcname,...)MAP(n,CALL,funcname,__VA_ARGS__)

#define CALL1 (...)CALLN(1,__VA_ARGS__)
#定义CALL2(...)CALLN(2,__VA_ARGS__)
#定义CALL3(...)CALLN(3,__VA_ARGS__)
// ...

CALL1(foo,int);
CALL2(bar,float,double);
CALL3(巴兹,随便,你想要);

结果:

  foo_int(); 
bar_float(); bar_double();
baz_whatever(); baz_you(); baz_want();


Suppose I have a macro, a simple one that just calls a function foo for different type:

#define FOO(type) foo_##type();

In one go, let's say I want to call this thing for multiple different types. Concretely;

foo_int();
foo_float();
foo_point2d();

I want to generate above code with a macro called FOO2.

#define FOO2(args...) --fill--here

And just to be complete, FOO2(int, float, point2d) should expand into the above small code snippet. Is this possible with macros and how to do a different, separate thing for each argument in a variadic macro token pack?

I am sure a question like this is already asked. I searched for couple of other results, showing some sort of FOR_EACH macro implementation that were quite complicated and general. That's why I decided to ask for my specific use-case and started a new question.

解决方案

Yes, it's possible, but requires multiple macros.

#define MAP1(m,t,...) m(t)
#define MAP2(m,t,...) m(t); MAP1(m,__VA_ARGS__)
#define MAP3(m,t,...) m(t); MAP2(m,__VA_ARGS__)
// ... add more as needed ...
#define MAP(n,...) MAP##n(__VA_ARGS__)

#define FOO(type) foo_##type()
#define FOON(n, ...) MAP(n, FOO, __VA_ARGS__)

FOON(3, int, float, double);

The above will generate:

foo_int(); foo_float(); foo_double();

If you don't want to specify the number as argument, add the following:

#define FOO1(...) FOON(1, __VA_ARGS__)
#define FOO2(...) FOON(2, __VA_ARGS__)
#define FOO3(...) FOON(3, __VA_ARGS__)
// ... add more as needed ...

And now you can just do:

FOO3(int, float, double);


With a bit more work you can even make the macro work with any function name:

#define MAP1(m,f,t,...) m(f,t)
#define MAP2(m,f,t,...) m(f,t); MAP1(m,f,__VA_ARGS__)
#define MAP3(m,f,t,...) m(f,t); MAP2(m,f,__VA_ARGS__)
// ...
#define MAP(n,...) MAP##n(__VA_ARGS__)

#define CALL(funcname, type) funcname##_##type()
#define CALLN(n, funcname, ...) MAP(n, CALL, funcname, __VA_ARGS__)

#define CALL1(...) CALLN(1, __VA_ARGS__)
#define CALL2(...) CALLN(2, __VA_ARGS__)
#define CALL3(...) CALLN(3, __VA_ARGS__)
// ...

CALL1(foo, int);
CALL2(bar, float, double);
CALL3(baz, whatever, you, want);

Result:

foo_int();
bar_float(); bar_double();
baz_whatever(); baz_you(); baz_want();

这篇关于每个令牌的可变参数宏扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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