0

I have a map with string and enum. I am getting an enum value as input and from that I need to get a string.

Below is the code snippet I have written for that:

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 "";
}

This way it is working. But every time it is looping through all the items in the map. Is there any better way to map enums to strings?

3
  • 1
    You can use 2 maps: std::map<std::string, Messages> m_StrToMessages; std::map<Messages, std::string> m_MessagesToStr; Commented May 1, 2021 at 17:28
  • 1
    Get rid of the map; Use a switch statement and just return the string value for each case. Commented May 1, 2021 at 17:40
  • Hey @Yar, any feedback on the 2 provided answers? Commented May 3, 2021 at 8:39

2 Answers 2

2

If you do not need that map for something else, then the easiest would be this, as suggested by @Casey :

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

But if you do need that map elsewhere (and of course not duplicate its content), you can use a bimap. Boost provides one, see boost::bimap. Its header-only, so pretty easy to integrate in your code.

There are some subtleties, so here is a quick example (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 );
}

If you have many values in that map, it could be worth it. And I'm sure initializing the values can be done in a much more efficient way, but I can't search that at present.

Sign up to request clarification or add additional context in comments.

3 Comments

Oops, missed the switch in first solution! Corrected.
Also, the break; statements are superfluous; the returns will cause them to be skipped.
@Casey Ah, yes, sure.
0

You could use a lookup 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]);

The table data type allows you to search by enum to find the text, or to search by the text to get the enum value.

You can also change the size of the table without changing the search code.

Since the table is tagged as static const, it will be initialized before run-time or accessed directly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.