Can't use enum class as unordered_map key

后端 未结 7 1421
后悔当初
后悔当初 2020-12-12 20:29

I have a class containing an enum class.

class Shader {
public:
    enum class Type {
        Vertex   = GL_VERTEX_SHADER,
        Geometry = GL_GEOMETRY_SHA         


        
7条回答
  •  无人及你
    2020-12-12 21:02

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

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

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

    enum class MyEnum {};
    
    std::unordered_map myMap;
    

    So you don't need to provide a specialization of std::hash, the template argument deduction does 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 
    using HashType = typename std::conditional::value, EnumClassHash, std::hash>::type;
    
    template 
    using MyUnorderedMap = std::unordered_map>;
    

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

    MyUnorderedMap myMap2;
    MyUnorderedMap myMap3;
    

    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 
    using HashType = typename std::conditional::value, std::hash::type>, std::hash>::type;
    

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

提交回复
热议问题