enum class as map key

I'm trying to use an enum class as a key in an unordered_map. But this fails to compile:
1
2
3
4
5
6
7
8
9
10
11
#include <unordered_map>

enum class E
{
	V
};

int main()
{
	std::unordered_map<E, int> m;
}
First it did compile but failed to link but only if I actually used operator[] (Not sure if I used the same compile options both time). I tried upgrading my version of gcc and now this code doesn't even compile. It says that std::hash is not specialized for type E.

Is this just a bug in gcc or what?
You need to provide a hash function object.


1
2
3
enum colour_t { CYAN, MAGENTA, YELLOW, BLACK } ;

std::unordered_map< colour_t, int, std::hash<int> > map = { { YELLOW, 31 }, { CYAN, 7 } } ;

It doesn't make sense that we should have to do this because enum class works perfect as std::map key.
std::less<> is available as a generalization for any type T on which the < comparison can be used.

The generalization for std::hash<> is not defined - only specializations are defined.
http://en.cppreference.com/w/cpp/utility/hash

Last edited on
Ok, so I guess I just have to specialize std::hash for my enum classes.
1
2
3
4
5
6
7
8
9
10
11
namespace std
{
	template <> 
	struct hash<E>
	{
		size_t operator()(const V& v) const
		{
			return hash<int>()(static_cast<int>(v));
		}
	};
}
Last edited on
> I guess I just have to specialize std::hash for my enum classes

Required only if we want to use a custom hash algorithm - something different hash from std::hash<int>. Otherwise, we can just specify std::hash<int> as a non-defaulted template parameter:

1
2
3
enum colour_t { CYAN, MAGENTA, YELLOW, BLACK } ;

std::unordered_map< colour_t, int, std::hash<int> > map ;
Topic archived. No new replies allowed.