2016-01-15 34 views
2

我有一個令牌列表,我想從中創建一個枚舉(小數)和一個字符串數組(稍後用於創建要枚舉的字符串映射)。這裏是我的嘗試:從預處理器標記創建字符串數組

#define TOKEN_LIST CUBE , SPHERE , CIRCLE 
#define CREATE_ARRAY_OF_STRINGS(...) const char* token[] = { __VA_ARGS__ }; 

CREATE_ARRAY_OF_STRINGS(TOKEN_LIST) 
// enum SHAPE_TYPE{ TOKEN_LIST }; // easy 

int main(int argc, char *argv[]) 
{ 
    return 1; 
} 

的問題是,如下TOKEN_LIST不字符串化如圖所示,當我與-E標誌進行編譯:

const char* token[] = { CUBE , SPHERE , CIRCLE }; 

int main(int argc, char *argv[]) 
{ 
    return 1; 
} 

const char* token[] = { CUBE , SPHERE , CIRCLE };應該const char* token[] = { "CUBE" , "SPHERE" , "CIRCLE" };

有任何其他方式來實現這與C + + 03?升壓處理器也許?

+0

爲什麼你需要這個? 如果您使用宏,這意味着您在代碼開始執行之前知道。所以你可以將它們存儲在變量中。並用於創建數組或直接在數組初始化中使用它們。 – MASh

+0

爲了自動更新字符串映射到枚舉。我只想在一點處註冊令牌並自動更新枚舉列表和地圖。但這不是我需要幫助的部分。 – Olumide

回答

2

如果您願意在某種程度上更改TOKEN_LIST的格式,您可以使用Boost.Preprocessor輕鬆完成此操作。

下面是一個使用,而不是逗號分隔列表的Boost.Preprocessor 序列的例子:

#define GENERATE_STRING(maZ, maIdx, maTokens) \ 
    BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(maIdx, maTokens)) 

#define GENERATE_STRINGS(maTokens) \ 
    BOOST_PP_ENUM(BOOST_PP_SEQ_SIZE(maTokens), GENERATE_STRING, maTokens) 

#define TOKEN_LIST (CUBE)(SPHERE)(CIRCLE) 

const char* token[] = { GENERATE_STRINGS(TOKEN_LIST) } 

enum ShapeType { 
    BOOST_PP_SEQ_ENUM(TOKEN_LIST) 
}; 

因爲你似乎必須...__VA_ARGS__(這是一個C +訪問+03功能),您應該也可以使用Boost.Preprocessor 元組(用括號括起來的以逗號分隔的列表);通過支持可變宏,Boost.Preprocessor能夠隱式確定元組大小。但是,我沒有這方面的經驗,所以我不能提供代碼示例。


maZ說法是Boost.Preprocessor重複宏的實現功能。有三種:z(由枚舉式函數使用),d(由while式函數使用)和r(由for-style函數使用)。只有嵌套這些構造時纔有用,因爲它允許更快的預處理。如果GENERATE_STRING自己調用枚舉函數,那麼在預處理器上使用BOOST_PP_ENUM_ ## maZ比在嵌套調用中使用BOOST_PP_ENUM更容易(但只要不超過編譯器的預處理限制,後者也適用)。

+0

'maZ'在'GENERATE_STRING()'中扮演什麼角色? – Olumide

+0

@Olumide答案展開。 – Angew

+0

謝謝。爲什麼所有的論點都以「ma」開頭? 'z'的情況也是如此。我問,因爲你在代碼和解釋中使用了不同的情況。 – Olumide