0

I am trying to build a function that converts an item from an enum to its corresponding string. The enums I use are fairly long, so I didn't want to use a switch-case. I found a method using boost::unordered_map very convenient, but I don't know how to make a default return (when there is no item matching the enum).

const boost::unordered_map<enum_type, const std::string> enumToString = boost::assign::map_list_of
(data_1, "data_1")
(data_2, "data_2");

I tried to create an additional function:

std::string convert(enum_type entry)
{
    if (enumToString.find(entry))       // not sure what test to place here, 
        return enumToString.at(entry);  //because the find method returns an iter
    else
        return "invalid_value";
}

I even tried something exceedingly wrong:

std::string convert(enum_type entry)
{
    try{
        return enumToString.at(entry);
    }
    catch(...){
        return "invalid_value";
    }
}

Result: evil "Debug" runtime error. Can somebody give me a suggestion on how to either
1) find an easier method to convert enum to a string with the same name as the enum item
2) find a way to use already built boost methods to get a default value from a hash map (best option)
3) find what to place in the test to use a function that returns either the pair of the key-value, or a different string if the key is not found in the map.
Thank you very much.

4

2 回答 2

2

For the conversion routine:

std::string
convert( enum_type entry )
{
    boost::unordered_map<enum_type, std::string>::const_iterator
                        retval = enumToString.find();
    return retval == enumToString.end()
        ? "invalid_value"
        : retval->second;
}

Note that if the enum contains no assigned values, a simple char const* [] will do the trick.

于 2012-04-13T17:25:52.883 回答
0

This is not an explict answer to your question, but I recommend using another data structure:

Use a bidirectional map , e. g. Boost.Bimap

Boost.Bimap is a bidirectional maps library for C++. With Boost.Bimap you can create associative containers in which both types can be used as key. A bimap<X,Y> can be thought of as a combination of a std::map<X,Y> and a std::map<Y,X>.

With a bidirectional map (you can also implement a basic one with two std::unordered_map instances) you are able to:

  • Retrieve an enumerator for a std::string.
  • Retrieve a std::string for an enumerator.

If you encapsulate the retrieve methods in a template class you are able to minimize DRY. E. g. you can pass the enumerator/std::string associations via std::pair instances to the constructor which expects one std::initializer_list argument.

于 2014-07-28T09:32:08.780 回答