tags:

views:

661

answers:

6
+4  Q: 

String to Enum

Is there a way to associate a string from a text file with an enum value?

The problem is, I have a few enum values stored as string in a text file which I read on the fly on meeting some condition... Now I want to assign the read value to an enum.

What is the most effective way to do so? It needn't be the simplest approach.

+6  A: 

std::map< string, enumType> enumResolver;

tpdi
A: 

Parse the string yourself, match the string with a value (which is also an index to a map<string, enum>.

dirkgently
+10  A: 

You can set up a map that you can use over and over:

template <typename T>
class EnumParser
{
    map <string, T> enumMap;
public:
    EnumParser();

    T ParseSomeEnum(const string &value)
    { 
     map <string, T>::const_iterator iValue = enumMap.find(value);
     if (iValue  == enumMap.end())
      throw runtime_error("");
     return iValue->second;
    }
};

enum SomeEnum
{
    Value1,
    Value2
};
EnumParser<SomeEnum>::EnumParser()
{
    enumMap["Value1"] = Value1;
    enumMap["Value2"] = Value2;
}

enum OtherEnum
{
    Value3, 
    Value4
};
EnumParser<OtherEnum>::EnumParser()
{
    enumMap["Value3"] = Value3;
    enumMap["Value4"] = Value4;
}

int main()
{
    EnumParser<SomeEnum> parser;
    cout << parser.ParseSomeEnum("Value2");
}
Eclipse
Why not using an hasmap ? It'd make the lookup more efficient ? Well , it must tried and measure effectiveness as it may depend on the number of elements in your enum... With big enum, hasmap could make it a quicker way to get the value, isn't it?
yves Baumes
hash_map isn't part of the standard (and unordered_map was only added in TR1). Also, there's likely to be very little difference between hash_map and map unless you start having a very large number of enum values. In any case, it's an easy switch to make if profiling indicates something's too slow
Eclipse
+2  A: 

Using a std::map raises the question - how does the map get initialised? I would rather use a function:

enum E { A, B };

E f( const std::string & s ) {
   if ( s == "A" ) {
      return A;
    }
    else if ( s == "B" ) {
      return B;
    }
    else {
      throw "Your exception here";
    }
}
anon
how is initializing the map a problem?
You have to guarantee it gets done before you use it to map the strings. This is possible, but only by writing a function.
anon
My inclination is toward map, since look-up is fast, but Neil, your answer did get me thinking: enums are known at compile-time, as are their string representations. Is there an efficient, scalable way to implement all of this at compile-time?
veefu
veefu, the whole point is to do it at runtime. That is, for an unknown value of type Enum, retrieve its std::string representation. If all you want to support is an enum passed as template parameter, you can avoid the map overhead via template specialization. I don't see the usefulness though.
+2  A: 

I agree with many of the answers that std::map is the easiest solution.

If you need something faster, you can use a hash map. Perhaps your compiler already offers one, such as hash_map or the upcoming standard unordered_map, or you can get one from boost. When all the strings are known ahead of time, perfect hashing can be used as well.

Mark Ransom
+1  A: 

Look at Boost.Bimap, it provides bidirectional associations between two sets of values. You can also choose the underlying container.

Vadim Ferderer