简体   繁体   中英

C++ string to enum

Is there a simple way in C++ to convert a string to an enum (similar to Enum.Parse in C#)? A switch statement would be very long, so I was wondering if there is a simpler way to do this?

EDIT:

Thanks for all of your replies. I realized that there was a much simpler way to do it for my particular case. The strings always contained the charater 'S' followed by some number so i just did

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

and then did a switch on i.

A std::map<std::string, MyEnum> (or unordered_map ) could do it easily. Populating the map would be just as tedious as the switch statement though.

Edit : Since C++11, populating is trivial:

static std::unordered_map<std::string,E> const table = { {"a",E::a}, {"b",E::b} };
auto it = table.find(str);
if (it != table.end()) {
  return it->second;
} else { error() }

Use std::map<std::string, Enum> and use boost::map_list_of to easily initialize it.

Example,

enum X
{
   A,
   B,
   C
};

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

saw this example somewhere

#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(){}
};

I use this "trick" > http://codeproject.com/Articles/42035/Enum-to-String-and-Vice-Versa-in-C

After

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

insert

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

It works fine, if the values in the enum are not duplicates.

Example in code

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

vice versa

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

this worked for me:

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

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

There is no "built-in way", but there are ways to achieve this by storing the pair value-name in an array

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);

In short: there is none. In C++ enums are static values and not objects like in C#. I suggest you use a function with some if else statements.

It is not possible because the names are not available at runtime. During compilation each enum is replaced with the corresponding integer value.

While there is no direct solution, there are a few possible workarounds.

Take a look at this question: Easy way to use variables of enum types as string in C?

You can use macro to minimize repeating yourself. Here is the trick: Enums, Macros, Unicode and Token-Pasting

"Additional question: Is it possibile to handle undefined strings ? I mean if I try to get the value for responseHeaderMap["cookie"], what will be the value? (provided that "cookie" is not defined in the responseHeaderMap – bart s Nov 22 '16 at 12:04"

well, you can just make check before:

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

After "cookie" exist check, you can get it value with use:

responseHeaderMap["cookie"]

hope this help

不,您必须使用 if/then 构造,或者使用映射或哈希表或其他类型的关联数据结构来简化此操作。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM