テキストファイルの文字列を列挙値に関連付ける方法はありますか?
問題は次のとおりです。テキストファイルに文字列として格納されているいくつかの列挙値があり、ある条件を満たすときにその場で読み取ります...次に、読み取り値を列挙に割り当てます。
そうするための最も効果的な方法は何ですか?最も単純なアプローチである必要はありません。
何度も使用できるマップを設定できます。
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;
Boost.Bimap を見てください。これは、2つの値のセット間の双方向の関連付けを提供します。基になるコンテナを選択することもできます。
承認された回答には完全なリストが含まれていません。受け入れられた回答から作成した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)
これは、あなたの望むことですか?初期化は簡単で、インスタンス化は必要ありません。
使用法:
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[]
を使って 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";
}
}
ここからC++リフレクションライブラリを使用する: https://github.com/tapika/cppreflect
次のようなライブラリを含めることができます。
#include "cppreflect/cppreflect.h"
基本的な使用法:
列挙を宣言します:
DECLARE_ENUM( enumName,
// Prefix for all enums, "" if no prefix used.
"myenum_",
myenum_enumValue1,
myenum_enumValue2,
myenum_enumValue3 = 5,
// comment
myenum_enumValue4
);
変換ロジック:
列挙から文字列へ:
printf( EnumToString(myenum_enumValue3).c_str() );
=> "enumValue3"
文字列から列挙型へ:
enumName value;
if( !StringToEnum("enumValue4", value) )
printf("Conversion failed...");
=>
value == myenum_enumValue4
主な/コア機能はここにあります:
https://github.com/tapika/cppreflect/blob/master/cppreflect/enumreflect.h
文字列のハッシュを計算して、これを使用できます。
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;
}
文字列を自分で解析し、文字列を値(map<string, enum>
のインデックスでもある)と一致させます。