[英]C++ macro and templates
有沒有辦法通過
std::map<std::string, float>
作為宏的論據?
(問題是宏用來分割“,”
std::map<std::string
和
float>
作為單獨的論點。 我想避免這個。
不,沒有辦法做到這一點,沒有使用typedef。 例如,BOOST_FOREACH遇到了同樣的問題。
嘗試使用模板而不是宏。
Scott Meyers:有效的C ++第2項:更喜歡#defines的consts,enums和inline
是的,有一種方法,但它是間接的。
正如你所說,宏觀在解釋中相當愚蠢。 但它仍然可以識別括號。
示例: 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";
所以,是的,這是可能的,但宏必須明確定制來處理它。
一個不優雅的解決方法是將逗號“隱藏”在另一個宏中
#define ARGUMENT std::map<std::string, float>
YOUR_MACRO(ARGUMENT)
#undef ARGUMENT
但是,如果YOUR_MACRO
本身需要將另一個級別傳播到另一個宏,它將遇到同樣的問題。
幾個月前我有類似的東西,如果你使用宏並且參數包含逗號(','),你需要將它們包含在額外的父級中,即:
#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);
是的,這么長時間你可以安排它,以便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>);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.