在C ++中枚举的string
有没有办法将文本文件中的string与枚举值相关联?
问题是:我有一些枚举值作为string存储在一个文本文件中,我满足了一些条件,在飞行中阅读…现在我想分配读取值的枚举。
最有效的方法是什么? 它不需要是最简单的方法。
您可以设置一个可以反复使用的地图:
template <typename T> class EnumParser { map <string, T> enumMap; public: EnumParser(){}; T ParseSomeEnum(const string &value) { map <string, T>::const_iterator iValue = enumMap.find(value); if (iValue == enumMap.end()) throw runtime_error(""); return iValue->second; } }; enum SomeEnum { Value1, Value2 }; EnumParser<SomeEnum>::EnumParser() { enumMap["Value1"] = Value1; enumMap["Value2"] = Value2; } enum OtherEnum { Value3, Value4 }; EnumParser<OtherEnum>::EnumParser() { enumMap["Value3"] = Value3; enumMap["Value4"] = Value4; } int main() { EnumParser<SomeEnum> parser; cout << parser.ParseSomeEnum("Value2"); }
std::map< string, enumType> enumResolver;
我同意很多答案, std::map
是最简单的解决scheme。
如果你需要更快的东西,你可以使用哈希映射。 也许你的编译器已经提供了一个,比如hash_map
或即将到来的标准unordered_map,或者你可以从boost中获得一个。 当所有的string提前知道时,也可以使用完美的散列 。
看看Boost.Bimap ,它提供了两组值之间的双向关联。 您也可以select底层容器。
使用std::map
引发了一个问题:地图如何被初始化? 我宁愿使用一个函数:
enum E { A, B }; E f( const std::string & s ) { if ( s == "A" ) { return A; } else if ( s == "B" ) { return B; } else { throw "Your exception here"; } }
这是你想要的吗? 初始化是直接的,不需要实例化。
用法:
enum SomeEnum { ENUM_ONE, ENUM_TWO, ENUM_THREE, ENUM_NULL }; DEFINE_PAIRLIST(CEnumMap, SomeEnum) INIT_PAIRLIST(CEnumMap)= { {"One", ENUM_ONE}, {"Two", ENUM_TWO}, {"Three", ENUM_THREE}, {"", ENUM_NULL} }; main{ // Get enum from string SomeEnum i = CEnumMap::findValue("One"); // Get string from enum SomeEnum eee = ENUM_ONE; const char* pstr = CEnumMap::findKey(eee); ... }
图书馆:
template <class T> struct CStringPair { const char* _name; T _value; }; template <class T, class Derived> struct CStringPairHandle { typedef CStringPair<T> CPair; static const CStringPair<T> * getPairList(){ return Derived::implementation(); } static T findValue(const char* name){ const CStringPair<T> * p = getPairList(); for (; p->_name[0]!=0; p++) if (strcmp(name,p->_name)==0) break; return p->_value; } static const char* findKey(T value){ const CStringPair<T> * p = getPairList(); for (; p->_name[0]!=0; p++) if (strcmp(value,p->_value)==0) break; return p->_name; }; }; #define DEFINE_PAIRLIST(name, type) struct name:public CStringPairHandle<type, name>{ \ static CPair _pairList[]; \ static CPair* implementation(){ \ return _pairList; \ }}; #define INIT_PAIRLIST(name) name::CPair name::_pairList[]
自己parsingstring,将string与值匹配(也是map<string, enum>
的索引。
接受的答案不包含完整列表。 我添加了我从接受的答案中创build的EnumParser.h
,希望它可以帮助
#include <string> #include <map> using namespace std; template <typename T> class EnumParser { map<string, T> enumMap; public: EnumParser(){}; T ParseSomeEnum(const string &value) { typename map <string, T>::const_iterator iValue = enumMap.find(value); if (iValue == enumMap.end()) throw runtime_error(""); return iValue->second; } };
用法很简单:
enum FieldType { Char, Integer, Long, Fixed, Price, Date, Time }; EnumParser<FieldType>::EnumParser() { enumMap["Char"] = Char; enumMap["Integer"] = Integer; enumMap["Long"] = Long; enumMap["Fixed"] = Fixed; enumMap["Price"] = Price; enumMap["Date"] = Date; enumMap["Time"] = Time; }
使用:
EnumParser<FieldType> fieldTypeParser; FieldType val = fieldTypeParser.ParseSomeEnum(stringValue)
你可以计算string的散列,然后使用这个:
template <typename H, typename E> E map_hash(H const key, std::initializer_list<std::pair<H, E>> const il) { auto const i( std::find_if(il.begin(), il.end(), [key](auto& p) { return p.first == key; } ) ); assert(i != il.end()); return i->second; }