c++ - 不能使用枚举类作为 unordered_map 键

标签 c++ c++11 map enums enum-class

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

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::hashEnumClassHash 取决于在 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>>;

现在您可以将 MyUnorderedMapenum 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/

相关文章:

c++ - 为什么C++被称为语言联盟?

c++ - 如何仅强制类的智能指针实例?

java - HashMap 中的部分搜索

ios - 点击 MKAnnotationView 取消选择它并隐藏它的标注

c++ - 在 C++ 帮助中使用 setprecision()

c++ - 游戏引擎: What are scene graphs?

c++ - 如何在不添加换行符的情况下将文本附加到 QPlainTextEdit,并将滚动保持在底部?

c++ - 0xC0000005 多线程动画错误

c++ - 生成 Conway 'look and say' 数字

java - Java 的泛型问题