不能使用枚举类作为unordered_map键 [英] Can't use enum class as unordered_map key

查看:247
本文介绍了不能使用枚举类作为unordered_map键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含枚举类的类。

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?

推荐答案

我使用函子对象计算枚举类的散列:

I use a functor object to calculate hash of enum class:

struct EnumClassHash
{
    template <typename T>
    std::size_t operator()(T t) const
    {
        return static_cast<std::size_t>(t);
    }
};

现在你可以使用它作为第三个模板参数 std :: unordeder_map

Now you can use it as 3rd template-parameter of std::unordeder_map:

enum class MyEnum {};

std::unordered_map<MyEnum, int, EnumClassHash> myMap;

所以你不需要提供 std :: hash ,模板参数扣除做作业。此外,您可以使用使用并使用您自己的 unordered_map 使用 std :: hash EnumClassHash 取决于类型:

So you don't need to provide a specialization of std::hash, the template argument deduction do the job. Furthermore, you can use the word using and make your own unordered_map that use std::hash or EnumClassHash depending on the Key type:

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 c $ c> enum class 或其他类型:

Now you can use MyUnorderedMap with enum class or another type:

MyUnorderedMap<int, int> myMap2;
MyUnorderedMap<MyEnum, int> myMap3;

理论上, HashType 可以使用 std :: underlying_type ,然后 EnumClassHash 就不是必需的。这可能是这样,但我还没有尝试

Theoretically, HashType could use std::underlying_type and then the EnumClassHash will not be necessary. That could be something like this, but I haven't tried yet:

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 可能是一个非常好的标准提案。

If using std::underlying_type works, could be a very good proposal for the standard.

这篇关于不能使用枚举类作为unordered_map键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆