我有一个包含枚举类的类。
class Shader {
public:
enum class Type {
Vertex = GL_VERTEX_SHADER,
Geometry = GL_GEOMETRY_SHADER,
Fragment = GL_FRAGMENT_SHADER
};
//...
然后,当我在另一个类中实现以下代码时...
std::unordered_map<Shader::Type, Shader> shaders;
...我得到一个编译错误。
...usr/lib/c++/v1/type_traits:770:38:
Implicit instantiation of undefined template 'std::__1::hash<Shader::Type>'
是什么导致了这里的错误?
最佳答案
我使用仿函数对象来计算枚举类
的哈希:
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
现在您可以将它用作 std::unordered_map
的第三个模板参数:
enum class MyEnum {};
std::unordered_map<MyEnum, int, EnumClassHash> myMap;
所以你不需要提供 std::hash
的特化,模板参数推导就可以了。此外,您可以使用单词 using
并制作自己的 unordered_map
使用 std::hash
或 EnumClassHash
取决于在 Key
上输入:
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, EnumClassHash, std::hash<Key>>::type;
template <typename Key, typename T>
using MyUnorderedMap = std::unordered_map<Key, T, HashType<Key>>;
现在您可以将 MyUnorderedMap
与 enum class
或其他类型一起使用:
MyUnorderedMap<int, int> myMap2;
MyUnorderedMap<MyEnum, int> myMap3;
理论上,HashType
可以使用 std::underlying_type
,那么 EnumClassHash
就没有必要了。可能是这样的,但我还没有尝试过:
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, std::hash<std::underlying_type<Key>::type>, std::hash<Key>>::type;
如果使用 std::underlying_type
有效,可能是一个非常好的标准提案。
关于c++ - 不能使用枚举类作为 unordered_map 键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18837857/