【问题标题】:C++ string to enumC++ 字符串到枚举
【发布时间】:2011-11-02 01:07:40
【问题描述】:

C++ 中是否有一种简单的方法可以将字符串转换为枚举(类似于 C# 中的Enum.Parse)? switch 语句会非常长,所以我想知道是否有更简单的方法来做到这一点?

编辑:

感谢您的所有回复。我意识到对于我的特殊情况,有一种更简单的方法可以做到这一点。字符串总是包含字符“S”,后跟一些数字,所以我就这样做了

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

然后打开i。

【问题讨论】:

  • 很遗憾,您甚至不能将switch 与字符串一起使用。
  • 我在an answer to another question 中演示了枚举-> 字符串映射的宏实现。您也可以轻松地将其调整为在另一个方向上工作。如果可以的话,最好避免多次命名枚举数。
  • 请参阅here,了解使用 Boost 将字符串一般转换为枚举和其他基于整数的类型的巧妙方法!

标签: c++ string enums


【解决方案1】:

std::map<std::string, MyEnum>(或unordered_map)可以轻松做到。不过,填充地图与 switch 语句一样乏味。

编辑:从 C++11 开始,填充是微不足道的:

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() }

【讨论】:

  • +1 for std::unordered_map:对于大型枚举,散列可能是最简单、最快的解决方案。
  • 我有一个答案,包括另一个关于另一种方式(枚举到字符串)的问题的代码,但它可以很容易地适应任何一种方式。 stackoverflow.com/a/11586083/5987
  • 由于条件中的init-statement,此示例在 C++17 之前无法编译。
  • @dimo414 你是对的。不幸的是,在我创建答案很久之后,其他人添加了该代码。我会解决的。
【解决方案2】:

使用std::map&lt;std::string, Enum&gt;boost::map_list_of轻松初始化它。

例子,

enum X
{
   A,
   B,
   C
};

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

【讨论】:

  • 现在好像是boost::assign::map_list_of
【解决方案3】:

在某处看到这个例子

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

【讨论】:

  • @Napalm 我刚刚重新编译并测试了它。你可能没有包含 .
  • 旧但很好的答案。附加问题:是否可以处理未定义的字符串?我的意思是,如果我尝试获取 responseHeaderMap["cookie"] 的值,那么值是多少? (前提是 responseHeaderMap 中没有定义“cookie”
  • 与这么多这样的答案一样,这个可以使用一个如何调用代码的示例以及预期的结果。要使用这个结构,显然开发人员必须声明一个 responseHeaderMap 类型的变量,然后在该变量上调用 [] 运算符。
  • 这将适用于如下调用:responseHeaders r = responseHeaderMap()[str];
【解决方案4】:

我使用这个“技巧”> 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 FORM f = ...
const std::string& str = EnumString< FORM >::From( f );

反之亦然

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

【讨论】:

    【解决方案5】:

    没有“内置方式”,但有一些方法可以通过将对值名称存储在数组中来实现这一点

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

    【讨论】:

    • 不要使用成对的向量,使用地图!
    • 参加聚会很晚,但是由于错误的容器而被否决的投票似乎很小。虽然地图看起来很明显,但可能还有其他考虑...
    • @FerdinandBeyer Map 允许 O(log n) 查找,但需要更大的空间。正确排序的对向量允许在更小的空间内以相同的速度进行查找。对于静态数量的项目,几乎肯定不需要地图。
    • 问题是字符串到枚举,而不是枚举到字符串
    【解决方案6】:

    这对我有用:

    enum NODES { Cone = 1, BaseColor = 2, NONE = 0 };
    
    std::map<std::string, NODES> nodeMap;
    nodeMap["Cone"] = NODES::Cone;
    nodeMap["BaseColor"] = NODES::BaseColor;
    

    【讨论】:

      【解决方案7】:

      简而言之:没有。在 C++ 中,枚举是静态值,而不是像 C# 中的对象。我建议您使用带有一些 if else 语句的函数。

      【讨论】:

        【解决方案8】:

        这是不可能的,因为名称在运行时不可用。在编译期间,每个枚举都被替换为相应的整数值。

        【讨论】:

          【解决方案9】:

          虽然没有直接的解决方案,但有一些可能的解决方法。

          看看这个问题:Easy way to use variables of enum types as string in C?

          【讨论】:

            【解决方案10】:

            您可以使用宏来尽量减少重复自己。这是诀窍:Enums, Macros, Unicode and Token-Pasting

            【讨论】:

              【解决方案11】:

              不,您必须使用 if/then 构造,或使用映射或哈希表或其他类型的关联数据结构来促进这一点。

              【讨论】:

                【解决方案12】:

                "附加问题:是否可以处理未定义的字符串?我的意思是,如果我尝试获取 responseHeaderMap["cookie"] 的值,该值将是什么?(前提是 responseHeaderMap 中没有定义"cookie" – bart s 2016 年 11 月 22 日 12:04"

                好吧,你可以先检查一下:

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

                “cookie”存在检查后,您可以通过使用获取它的值:

                responseHeaderMap["cookie"]
                

                希望有帮助

                【讨论】:

                  猜你喜欢
                  • 2011-09-11
                  • 2014-02-22
                  • 1970-01-01
                  • 2021-11-16
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-10-18
                  • 1970-01-01
                  相关资源
                  最近更新 更多