2010-08-25 114 views
7

考慮這個宏:可變參數的宏零個參數,和逗號

#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ > 

當與零個參數使用它產生壞的代碼,因爲編譯器期望逗號之後的標識符。事實上,VC的預處理器足夠聰明,可以刪除逗號,但GCC不是。 由於宏不能超載,好像它需要一個單獨的宏這種特殊情況下得到它的權利,如:

#define MAKE_TEMPLATE_Z() template <typename T> 

有沒有什麼辦法讓它不引入第二個宏工作?

回答

9

不,因爲宏調用MAKE_TEMPLATE()根本沒有零參數;它有一個包含零標記的參數。

較早的預處理程序,顯然包括GCC在回答最初編寫時,有時候會根據您的希望解釋一個空的參數列表,但共識已經轉向更嚴格,更窄的擴展,這更符合標準。

得到的答案下面工作,省略號之前定義一個額外的宏參數:

#define MAKE_TEMPLATE(UNUSED, ...) template <typename T, ## __VA_ARGS__ > 

,然後第一個參數之前總是把一個逗號當列表不爲空:

MAKE_TEMPLATE(, foo) 

舊的回答

根據http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html,GCC支持這一點,只是不透明。

語法是:

#define MAKE_TEMPLATE(...) template <typename T, ## __VA_ARGS__ > 

無論如何,都還支持可變參數模板中的C++ 0x模式,這是遠優選的。

+0

謝謝。順便說一句,這是標準的行爲,還是一個GCC的東西? – uj2 2010-08-25 06:14:54

+1

@ uj2:這是GCC;標準只禁止空的可變參數列表。順便說一句,這是混合C99與C++,所以這段代碼是嚴格的非標準的,除非你在C++ 0x ...在這種情況下,你應該... – Potatoswatter 2010-08-25 06:16:48

+0

不介意模板,它只是一個玩具的例子。這怎麼會是0x,C++ 98/03沒有定義可變宏? – uj2 2010-08-25 06:22:13

1

在GCC的情況下,你需要把它寫這樣的:

#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ > 

如果__VA_ARGS__是空的,GCC的預處理器去除了之前的逗號。

0

首先要小心可變宏不是當前C++的一部分。看來他們會在下一個版本中。目前他們只有在C99編程時才符合要求。

對於零參數的可變參數宏,有一些技巧可以檢測到這一點,並在宏週期中對其進行編程。 Googel爲empty macro arguments