有沒有辦法通過C++宏和模板
std::map<std::string, float>
作爲參數傳遞給宏?
(問題是, 「」 用於由宏分裂
std::map<std::string
和
float>
作爲獨立參數。我想避免這種情況。
有沒有辦法通過C++宏和模板
std::map<std::string, float>
作爲參數傳遞給宏?
(問題是, 「」 用於由宏分裂
std::map<std::string
和
float>
作爲獨立參數。我想避免這種情況。
一個不起眼的解決方法是「隱藏」另一個宏內的逗號
#define ARGUMENT std::map<std::string, float>
YOUR_MACRO(ARGUMENT)
#undef ARGUMENT
但是,如果YOUR_MACRO
本身需要將其另一個級別傳播到另一個宏,它將遇到同樣的問題。
'typedef'克服了嵌套宏問題,但更具永久性。 – 2010-02-19 08:42:42
我第二種'typedef'方法。每當有一個替代品不涉及一個宏並提供相同的易用性......你最好沒有一個宏。 – 2010-02-19 09:32:06
哦,真是太酷了。如果可以的話,我會給你+10。謝謝! – 2013-02-08 07:40:37
不,沒有辦法做到這一點,缺少使用typedef。例如,BOOST_FOREACH遭受同樣的問題。
+1使用typedef – James 2010-02-19 09:32:21
有幾種方法,如果你需要進行一些預處理編程。儘管這可能會給用戶帶來一些負擔,這取決於你所追求的內容,並且需要對宏進行量身定製來處理它......查看我的答案。 – 2010-02-19 09:33:42
嘗試使用模板而不是宏。
斯科特邁爾斯:C++有效 項目2:不想consts,枚舉和內聯到#define語句
'項目2'在這裏不適用:它沒有提到模板,只是常量......雖然我同意一般的觀點,但如果它總是可能的話......那將會很棒。 – 2010-02-19 09:14:54
它是第2項的內聯。我在這裏提到模板,因爲宏不關心類型,這就是爲什麼你通常不能用普通函數替換它們。但是使用模板可以讓你做到這一點。我認爲邁爾使用最小/最大宏對模板進行演示。 – Totonga 2010-02-19 09:55:24
我有類似的東西在幾個月前,如果你使用宏的,並有包含參數的逗號(「」 ),你需要包裹於額外parenthasis即:
#define DEF(ret,conv,name,args) typedef ret (conv * name)(args)
//usage
DEF(void,__cdecl,Foo,(int a1, string a2));
這種方法可能與某些東西衝突/在某些情況下無效的,這樣的例子(它導致它成爲一個無效的C樣式轉換):
#define MY_VAR(type,name) type name
//usage
MY_VAR((std::map<std::string, float>),Map);
雖然有一種解決此問題的方法,但它需要您的編譯器支持可變宏(GCC | MSVC):
#define _W(...) __VA_ARGS__
#define VAR(x,y) x y
VAR(_W(std::map<std::string, float>),Map);
是的,有一種方法,它是間接的。
正如你所說,一個宏在其解釋中相當愚蠢。但它仍然認可括號。
實施例:BOOST_MPL_ASSERT((boost::is_same<int,int>))
它通過使用括號的另一電平,由此形成Tuple
(從宏觀角度)。
如果您使用Boost.Preprocessor庫,您可以輕鬆地「解開」Tuple
以免其內容受到損害。不幸的是,你應該知道前期一個元組的大小,所以你需要一個額外的參數
#define MY_MACRO(Size, TemplatedType, Name)\
BOOST_PP_TUPLE_REM(Size)(TemplatedType) Name
而且在行動:
MY_MACRO(2, (std::map<int,std::string>), idToName);
// expands to 'std::map<int,std::string> idToName'
idToName[1] = "Smith";
所以,是的,它是可能的,但宏必須是明確定製來處理它。
我還應該補充一點,它可能很麻煩,因爲用戶需要計算',':/ – 2010-02-19 09:36:29
是的,只要您能安排它,std::map<std::string, float>
就是您的最終參數或唯一參數。只需使用__VA_ARGS__
,例如:
#define MAKE_A_NEW_ONE_OF_THESE(a, ...) __VA_ARGS__ *a = new __VA_ARGS__
MAKE_A_NEW_ONE_OF_THESE(pMyMap, std::map<std::string, float>);
我認爲他們聽說你第一次...... – 2010-02-19 08:38:23
難道這就是爲C?還是C++? – AnT 2010-02-19 08:39:43
只是好奇,我們可以看到有問題的宏嗎?可能有更好的方法來完成你使用它的任何任務。 – 2010-02-19 08:43:16