variable validar utiliza tipo sirven recorrer que para los enum ejemplo como clase c++ c++11 map enums enum-class

c++ - validar - No se puede usar la clase enum como clave desordenada_mapa



validar enum java (7)

Agregue esto al encabezado que define MyEnumClass:

namespace std { template <> struct hash<MyEnumClass> { size_t operator() (const MyEnumClass &t) const { return size_t(t); } }; }

Tengo una clase que contiene una clase enum.

class Shader { public: enum class Type { Vertex = GL_VERTEX_SHADER, Geometry = GL_GEOMETRY_SHADER, Fragment = GL_FRAGMENT_SHADER }; //...

Luego, cuando implemente el siguiente código en otra clase ...

std::unordered_map<Shader::Type, Shader> shaders;

... Recibo un error de compilación.

...usr/lib/c++/v1/type_traits:770:38: Implicit instantiation of undefined template ''std::__1::hash<Shader::Type>''

¿Qué está causando el error aquí?


Como señaló KerrekSB, debe proporcionar una especialización de std::hash si desea usar std::unordered_map , algo así como:

namespace std { template<> struct hash< ::Shader::Type > { typedef ::Shader::Type argument_type; typedef std::underlying_type< argument_type >::type underlying_type; typedef std::hash< underlying_type >::result_type result_type; result_type operator()( const argument_type& arg ) const { std::hash< underlying_type > hasher; return hasher( static_cast< underlying_type >( arg ) ); } }; }


Cuando usas std::unordered_map , sabes que necesitas una función hash. Para los tipos incorporados o STL , hay valores predeterminados disponibles, pero no para los definidos por el usuario. Si solo necesitas un mapa, ¿por qué no pruebas std::map ?



Tratar

std::unordered_map<Shader::Type, Shader, std::hash<std::underlying_type<Shader::Type>::type>> shaders;


Una solución muy simple sería proporcionar un objeto de función hash como este:

std::unordered_map<Shader::Type, Shader, std::hash<int> > shaders;

Eso es todo por una clave enum, no es necesario proporcionar una especialización de std :: hash.


Utilizo un objeto de functor para calcular el hash de la enum class :

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

Ahora puede usarlo como el tercer parámetro de plantilla de std::unordered_map :

enum class MyEnum {}; std::unordered_map<MyEnum, int, EnumClassHash> myMap;

Por lo tanto, no necesita proporcionar una especialización de std::hash , la deducción del argumento de la plantilla hace el trabajo. Además, puede usar la palabra using y crear su propio EnumClassHash unordered_map que use std::hash o EnumClassHash dependiendo del tipo de 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>>;

Ahora puedes usar MyUnorderedMap con la enum class u otro tipo:

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

Teóricamente, HashType podría usar std::underlying_type y luego EnumClassHash no será necesario. Eso podría ser algo como esto, pero aún no lo he intentado :

template <typename Key> using HashType = typename std::conditional<std::is_enum<Key>::value, std::hash<std::underlying_type<Key>::type>, std::hash<Key>>::type;

Si se usa std::underlying_type , podría ser una muy buena propuesta para el estándar.