2016-01-22 39 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 –