2011-03-19 50 views
11

创建可变宏指令的诀窍是什么?它会扩展到FOOn(a1, a2, a3,..., an)的值为n在您选择的任何预先选定的有界范围内?也就是说,FOO(a)应该扩大到FOO1(a),FOO(a, b, c)FOO3(a, b, c)等我知道有一个标准的技巧,但我似乎无法找到它。可变宏观把戏

请随时将此问题标记为重复项,如果答案还有其他问题,请将其关闭。我怀疑有但我找不到它。

+0

这篇文章有什么,你可能会发现有用:http://stackoverflow.com/ques tions/3420459/c-preprocessor-macro-overloading – Mat 2011-03-19 23:00:58

+0

请参阅此处的答案:http://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments – Anycorn 2011-03-19 23:14:54

+0

@aaa:答案问题不回答这个问题。由@Mat链接的问题更类似,但我不认为它是完全重复的。 – 2011-03-20 00:26:34

回答

7

这个职位Variadic macro to count number of arguments有你在找我相信。看第一个和第二个答复。

+0

谢谢,这个链接正是我所需要的。它比发布的潜在重复要好得多。 – 2011-03-20 00:44:18

+0

任何想法如何解决c99中的零参数? – mchiasson 2015-06-05 16:51:06

+0

链接已经消失,url给出了错误的DNS错误 – ACyclic 2016-05-22 17:06:12

11
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N 
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1) 

#define FOO_IMPL2(count, ...) FOO ## count (__VA_ARGS__) 
#define FOO_IMPL(count, ...) FOO_IMPL2(count, __VA_ARGS__) 
#define FOO(...) FOO_IMPL(VA_NARGS(__VA_ARGS__), __VA_ARGS__) 

FOO(a) 
FOO(a, b) 
FOO(a, b, c) 

的调用都替换为:

FOO1 (a) 
FOO2 (a, b) 
FOO3 (a, b, c) 
+0

优秀的答案,但是如何在调用'FOO()'时解决零参数情况,它应该扩展到'FOO0()',但是你的解决方案展开为'FOO1()'?我想知道如何在纯C99中执行此操作(无GNU扩展) – mchiasson 2015-06-05 16:48:22

+0

@mchiasson:据我所知,在标准C中没有办法做到这一点。您必须将至少一个标记传递给'__VA_ARGS__ ';你不能用空的参数列表调用这样的宏。 – 2015-06-05 21:39:44

5

提高涂谨申答案补充一定的灵活性:

#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N 
#define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 4, 3, 2, 1, 0) 
#define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__) 
#define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__) 
#define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__) 

#define MyMacro0() Also works without arguments. 
#define MyMacro2(x,y) [x...y] 
#define MyMacro(...) VARARG(MyMacro, __VA_ARGS__) 

MyMacro() 
MyMacro(a) 
MyMacro(a, b) 
MyMacro(a, b, c) 

输出:

Also works without arguments. 
MyMacro1(a) 
[a...b] 
MyMacro3(a, b, c) 
+0

优秀的答案,但'## __ VA_ARGS__'只适用于GNU扩展。你知道如何为c99解决这个问题吗? – mchiasson 2015-06-05 16:49:39