Reputation: 14615
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.
Upvotes: 0
Views: 1230
Reputation: 4080
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 astd::map<X,Y>
and astd::map<Y,X>
.
With a bidirectional map (you can also implement a basic one with two std::unordered_map
instances) you are able to:
std::string
.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.
Upvotes: 0
Reputation: 153929
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.
Upvotes: 2