簡體   English   中英

C ++宏和模板

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM