2016-01-22 38 views
0

我有一個配置文件,其中包含一個枚舉的字符串表示形式。有很多不同的枚舉值。加載配置後,我需要從它的字符串表示中找出枚舉值。忽略宏,我能想到的唯一方法就是創建一個可怕的查找函數,對每個可能的值進行字符串比較。例如:根據字符串表示方式設置枚舉值

typedef enum Fields 
{ 
    FieldFlagNone, 
    FieldFlagOperation, 
    FieldFlagFormat, 
    ... 
} 


Fields getFieldEnum(string fieldName){ 
    if(fieldName.compare("FieldFlagNone") == 0){ 
    return FieldFlagNone; 
    }else if(fieldName.compare("FieldFlagOperation") == 0){ 
    return FieldFlagOperation; 
    }else if(fieldName.compare("FieldFlagFormat") == 0){ 
    return FieldFlagFormat; 
    ... 
} 

是否有更快或更簡潔的方法來達到預期效果?

+2

['std :: unordered_map '](http://en.cppreference.com/w/cpp/container/unordered_map)? – BoBTFish

+0

這會減少代碼量,謝謝。我猜測,當字符串是枚舉值的精確表示時,沒有辦法直接查找枚舉值? –

回答

2

您可以使用std::unordered_map<std::string, Fields>,這將加速從線時間常數時間的轉換:

std::unordered_map<std::string, Fields> fieldsLookupTable { 
    { "FieldFlagNone", FieldFlagNone }, 
    ... 
}; 

爲了使它更簡潔,可以用一些宏:

#define LOOKUP_TABLE_ENTRY(x) { #x, x } 

然後:

std::unordered_map<std::string, Fields> fieldsLookupTable { 
    LOOKUP_TABLE_ENTRY(FieldFlagNone), 
    LOOKUP_TABLE_ENTRY(FieldFlagOperation), 
    ... 
}; 

如果你想在消除重複方面真的硬派,喲ü可以做這樣的事情:

#define ENUM_MODE_DEFINE 0 
#define ENUM_MODE_LOOKUP 1 

#define ENUM_BEGIN(x) \ 
#if ENUM_MODE == ENUM_MODE_DEFINE \ 
typedef enum x { \ 
#else \ 
#define LOOKUP_TABLE_NAME x ## LookupTable \ 
std::unordered_map<std::string, x> LOOKUP_TABLE_NAME; \ 
#endif 

#define ENUM_ENTRY(x) \ 
#if ENUM_MODE == ENUM_MODE_DEFINE \ 
x, \ 
#else \ 
LOOKUP_TABLE_NAME[#x] = x; \ 
#endif 

#define ENUM_END \ 
#if ENUM_MODE == ENUM_MODE_DEFINE \ 
} \ 
#else \ 
#undef LOOKUP_TABLE_NAME \ 
#endif 

,然後定義你這樣的枚舉:

#define FIELDS \ 
ENUM_BEGIN(Fields) \ 
ENUM_ENTRY(FieldFlagNone) \ 
ENUM_ENTRY(FieldFlagOperation) \ 
... 
ENUM_END 

哪裏以前有枚舉的定義,現在會有這樣的:

#define ENUM_MODE ENUM_MODE_DEFINE 
FIELDS 

和其他地方你有查詢表,你說這個:

#define ENUM_MODE ENUM_MODE_LOOKUP 
FIELDS 

基本上,FIELDS宏使用宏ENUM_BEGIN,ENUM_ENTRYENUM_END宏,它們根據ENUM_MODE的值生成不同的代碼。如果將其定義爲ENUM_MODE_DEFINE,則FIELDS將生成枚舉定義。如果將其設置爲ENUM_MODE_LOOKUP,則會生成fieldsLookupTable。 這樣我們只使用了FIELDS中的enum條目名稱,所以如果您在那裏更改某些內容,查找表和枚舉定義將自動更改並且不會不同步。

+0

它是一個很好的答案。我現在正在使用unordered_map,但我不認爲我可以添加宏。不幸的是,VS不允許我以這種方式初始化地圖;必須創建一個空的並填充它(你在初始化程序btw中缺少一個=)。 –

+0

@UltimateGobblement您正在使用哪個版本的VS? –

+0

2010.顯然該功能在<2013 –