I have a class containing an enum class.
class Shader {
public:
enum class Type {
Vertex = GL_VERTEX_SHADER,
Geometry = GL_GEOMETRY_SHADER,
Fragment = GL_FRAGMENT_SHADER
};
//...
Then, when I implement the following code in another class...
std::unordered_map<Shader::Type, Shader> shaders;
...I get a compile error.
...usr/lib/c++/v1/type_traits:770:38:
Implicit instantiation of undefined template 'std::__1::hash<Shader::Type>'
What is causing the error here?
A very simple solution would be to provide a hash function object like this:
That's all for an enum key, no need to provide a specialization of std::hash.
As KerrekSB pointed out, you need to provide a specialization of
std::hash
if you want to usestd::unordered_map
, something like:Add this to header defining MyEnumClass:
When you use
std::unordered_map
, you know you need a hash function. For built-in orSTL
types, there are defaults available, but not for user-defined ones. If you just need a map, why don't you trystd::map
?This was considered a defect in the standard, and was fixed in C++14: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148
As of gcc 4.9.3, however, this resolution is not yet implemented in libstdc++: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970.
It was fixed in clang's libc++ in 2013: http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130902/087778.html
I use a functor object to calculate hash of
enum class
:Now you can use it as 3rd template-parameter of
std::unordered_map
:So you don't need to provide a specialization of
std::hash
, the template argument deduction does the job. Furthermore, you can use the wordusing
and make your ownunordered_map
that usestd::hash
orEnumClassHash
depending on theKey
type:Now you can use
MyUnorderedMap
withenum class
or another type:Theoretically,
HashType
could usestd::underlying_type
and then theEnumClassHash
will not be necessary. That could be something like this, but I haven't tried yet:If using
std::underlying_type
works, could be a very good proposal for the standard.