-
Enums and Templates
I am wondering if I can somehow return enum values from a method, using templates or otherwise. Here is an outline of what I want to do. The specific enums are declared outside the scope of the State class.
class State {
map<string, int> values;
//...
template <enum E>
E getEnumValue(const string& key) const;
}
I have never written any code using either templates or C++ enums before, so I don't really know where to start.
Thanks.
-
Why not test this idea with your compiler?
-
Code:
enum numbers { zero, one, two, three };
template<typename T> T foo(T t) { return t; }
int main()
{
std::cout << foo<numbers>(zero);
std::cout << foo<numbers>(one);
std::cout << foo<numbers>(two);
std::cout << foo<numbers>(three);
return 0;
}
Yah.
-
Why do you need a template? Is it because you want your class to work with different enum types? In that case I would expect the class would need to be templated and the values map would have to be a map<string, E>. You would still use typename or class inside the template declaration instead of enum.
-
Tonto: Yes, I know that enum values are integers.
Daved: I want instances of the State class to be able to return enum values instead of the integers it stores.
This is what I want to do (but in C++). And I know it uses reflection and an unchecked cast, but all I want to know is if this is possible in C++ at all.
Code:
import java.util.Map;
import java.util.HashMap;
public class State {
public Map<String, Integer> values = new HashMap<String, Integer>();
public enum MyEnum {MY_CONSTANT};
public <E extends Enum<E>> E getEnumValue(String key, Class<E> enumType) {
try {
E[] enumValues = (E[])enumType.getMethod("values").invoke(null);
return enumValues[values.get(key)];
} catch (Exception e) {
return null;
}
}
public static void main(String[] args) {
State s = new State();
s.values.put("!", State.MyEnum.MY_CONSTANT.ordinal());
System.out.println(s.getEnumValue("!", State.MyEnum.class));
System.out.println(s.getEnumValue("!", State.MyEnum.class).getClass().getName());
}
}
-
Not without manually writing some metadata - the compiler won't store the names of the enum values, just their numeric values.
You could try the experimental Boost.Enum, which uses macros to automatically generate the metadata.