2011-03-19 76 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