如何在 C++ 中使用映射将枚举值分配给字符串

how to assign the enum values to strings using map in C++

我有一个包含字符串和枚举的映射。我得到一个枚举值作为输入,我需要从中得到一个字符串。

下面是我为此编写的代码片段:

std::map<std::string, Messages> m_MessagesMap;

auto MessageID = GetMessageID();
GetStringFromEnum(MessageID);
std::string CJsonMessageUtil::GetStringFromEnum(Messages l_eMessages)
{
    for (auto it = m_MessagesMap.begin(); it != m_MessagesMap.end(); ++it)
    {
        if (it->second == l_eMessages)
            return it->first;
    }

    return "";
}

这样就可以了。但是每次它都会遍历地图中的所有项目。有没有更好的方法将枚举映射到字符串?

您可以使用查找 table:

enum Trees {REDWOOD, MAPLE, OAK, SYCAMORE, EUCALYPTUS};
struct Enum_Conversion_Table
{
    enum Trees value;
    const char * text;
};

static const Enum_Conversion_Table table[] =
{
    {REDWOOD, "Redwood"},
    //...
    {EUCALYPTUS, "Eucalyptus"},
};
static const unsigned int table_size =
    sizeof(table) / sizeof(table[0]);

table 数据类型允许您通过枚举搜索来查找文本,或者通过文本搜索来获取枚举值。

您也可以在不更改搜索代码的情况下更改 table 的大小。

由于table被标记为static const,它会在运行之前初始化或直接访问。

如果您不需要该地图来做其他事情,那么最简单的就是这个,正如@Casey 所建议的那样:

std::string
getString( EnumType et )
{
  switch( et )
  {
   case et1: return "string1";
   case et2: return "string2";
   ...
   default: assert(0);
  }
}

但如果您在其他地方确实需要该地图(当然不是复制其内容),您可以使用 bimap。 Boost 提供了一个,参见 boost::bimap。它 header-only,非常容易集成到您的代码中。

有一些微妙之处,所以这里是一个简单的例子 (runnable here):

#include <boost/bimap.hpp>
enum MyEnum
{
    hello, world
};

using MyMap = boost::bimap<std::string,MyEnum>;

int main()
{   
    MyMap m;
    m.insert( MyMap::value_type("hello", hello ) );
    m.insert( MyMap::value_type("world", world ) );

    std::cout << m.right.at( hello );
}

如果您在该地图中有很多值,那可能是值得的。而且我确信初始化值可以以更有效的方式完成,但我目前无法搜索。