是否有可能擁有2個具有相同名稱但參數不同的宏?像這樣:具有不同參數的相同名稱的宏
#define FI(value) do {l<<value; Doit(l); } while(0)
#define FI(value, level) do {l<<value ; Doit(l,level); } while(0)
是否有可能擁有2個具有相同名稱但參數不同的宏?像這樣:具有不同參數的相同名稱的宏
#define FI(value) do {l<<value; Doit(l); } while(0)
#define FI(value, level) do {l<<value ; Doit(l,level); } while(0)
這是不可能的。
符號名稱不能重新定義。與函數不同,宏不能重載。想象一下,邏輯宏是純粹的文本替換,那麼如何替換同一個實體的兩個不同的東西呢?
的替代性和更好的解決方案:
可以達到同樣的結果寫inline function。它爲您提供類型的額外優勢,可以檢查並避免宏的渾濁副作用。
一個定義規則與預處理器宏無關。而且,如果您之前使用過#undef,則可以重新定義宏。 –
@TadeuszKopec:你是對的。在預處理時對宏進行評估,並且實現ODR的編譯器從不會看到任何宏。 –
其實這是可能的。但是,關於重新定義,將導致編譯器警告。
有關詳細信息,請參閱本: http://efesx.com/2010/08/31/overloading-macros/
我其實在Visual Studio中試過這個: –
這是你真的應該用內聯函數的情況。知道任何關於您所使用的類型,一個可能的實現可能是這樣的:
template<typename T>
inline void fi(T & l, const T & value) {
l << value;
Doit(l);
}
template<typename T>
inline void fi(T & l, const T & value, const T & level) {
l << value;
Doit(l, level);
}
如果你遇到,你必須堅持宏的情況下,你必須努力,解決此限制,他們不能超載,至少不是每個標準。爲了「重載」它們,我們只需在宏名稱中寫入參數的數量,這是一種常見的方式(實際上,即使OpenGL庫使用此方法來「重載」C函數)。
#define FI1(value) do {l<<value; Doit(l); } while(0)
#define FI2(value, level) do {l<<value ; Doit(l,level); } while(0)
這會奏效。
#define FI(value, ...) FI_(value, ##__VA_ARGS__, 2, 1)
#define FI_(value, level, n, ...) FI##n(value, level)
#define FI1(value, ...) do {l << value; Doit(l);} while (0)
#define FI2(value, level) do {l << value; Doit(l, level);} while (0)
是的,它被稱爲「內聯函數」。 – Puppy
@DeMgG有些人不喜歡聽到它,但有些情況下我們需要宏。像循環的語法糖一樣。參見[BOOST_FOREACH](http://www.boost.org/doc/libs/1_52_0/doc/html/foreach.html)。當然,你的論點對這個例子來說非常有用。 – leemes
@leemes C++ 11的基於範圍的for-loop取代'BOOST_FOREACH' :) – fredoverflow