web-dev-qa-db-ja.com

列挙するC ++文字列

C++で文字列を列挙型に変換する簡単な方法はありますか(Enum.Parse C#)? switchステートメントはvery longになるので、これを行う簡単な方法があるかどうか疑問に思っていましたか?

編集:

返信ありがとうございます。私の特定のケースでは、もっと簡単な方法があることに気付きました。文字列には常に文字「S」とそれに続く数字が含まれていたので、

int i = atoi(myStr.c_str() + 1);

その後、iを切り替えました。

16
Daniel

std::map<std::string, MyEnum>(またはunordered_map)簡単にできます。ただし、マップにデータを入力することは、switchステートメントと同じくらい退屈です。

26
Mark Ransom

使用する std::map<std::string, Enum>および boost::map_list_of toeasilyそれを初期化します。

例、

enum X
{
   A,
   B,
   C
};

std::map<std::string, X> xmap = boost::map_list_of("A", A)("B", B)("C",C);
23
Nawaz

この例をどこかで見た

#include <map>
#include <string>

enum responseHeaders
{
    CONTENT_ENCODING,
    CONTENT_LENGTH,
    TRANSFER_ENCODING,
};

// String switch paridgam   
struct responseHeaderMap : public std::map<std::string, responseHeaders>
{
    responseHeaderMap()
    {
        this->operator[]("content-encoding") =  CONTENT_ENCODING;
        this->operator[]("content-length") = CONTENT_LENGTH;
        this->operator[]("transfer-encoding") = TRANSFER_ENCODING;
    };
    ~responseHeaderMap(){}
};
11
Guy L

この「トリック」を使用します> http://codeproject.com/Articles/42035/Enum-to-String-and-Vice-Versa-in-C

enum FORM {
    F_NONE = 0,
    F_BOX,
    F_CUBE,
    F_SPHERE,
};

インサート

Begin_Enum_String( FORM )
{
    Enum_String( F_NONE );
    Enum_String( F_BOX );
    Enum_String( F_CUBE );
    Enum_String( F_SPHERE );
}
End_Enum_String;

Enumの値が重複していない場合は正常に動作します。

コードの例

enum FORM f = ...
const std::string& str = EnumString< FORM >::From( f );

逆に

assert( EnumString< FORM >::To( f, str ) );
8

「組み込みの方法」はありませんが、ペアのvalue-nameを配列に格納することでこれを実現する方法があります

enum myEnum
{
    enumItem0,
    enumItem1,
    enumItem7 = 7,
    enumItem8
};

std::vector<std::pair<myEnum,std::string>>   gMap;

#define ADDITEM(x)  gMap.Push_back(std::pair<myEnum,std::string>(x,#x));

.....

ADDITEM(enumItem0);
ADDITEM(enumItem1);
ADDITEM(enumItem7);
ADDITEM(enumItem8);
5
cprogrammer

これは私のために働いた:

enum NODES { Cone = 1, BaseColor = 2, NONE = 0 };

std::map<std::string, NODES> nodeMap;
nodeMap["Cone"] = NODES::Cone;
nodeMap["BaseColor"] = NODES::BaseColor;
4
Elias

マクロを使用して、繰り返しを最小限に抑えることができます。ここにトリックがあります: 列挙型、マクロ、ユニコード、トークン貼り付け

2
jj1

要するに、何もありません。 C++では、列挙型は静的な値であり、C#のようなオブジェクトではありません。関数をいくつかのif elseステートメント。

2
Constantinius

直接的な解決策はありませんが、いくつかの可能な回避策があります。

この質問を見てください: Cで列挙型の変数を文字列として使用する簡単な方法?

1
TeaWolf

実行時に名前が使用できないため、これは不可能です。コンパイル中に、各列挙型は対応する整数値に置き換えられます。

1

「追加の質問:未定義の文字列を処理することは可能ですか?responseHeaderMap ["cookie"]の値を取得しようとすると、値はどうなりますか?(「cookie」がresponseHeaderMapで定義されていない場合) 16年11月22日12:04に

まあ、あなただけの前に確認することができます:

auto it = responseHeaderMap.find("cookie");
if (it != responseHeaderMap.end())
{
     // "cookie" exist, can take value 
}

「cookie」の存在チェック後、useを使用して値を取得できます。

responseHeaderMap["cookie"]

この助けを願っています

いいえ、if/then構造を使用するか、マップまたはハッシュテーブルまたはその他の種類の連想データ構造を使用して、これを容易にする必要があります。

0
mwigdahl