standard librerias library las funcion estandar diseño dev definicion clasificacion clases bibliotecas biblioteca c++ arrays c++11 hash-function unordered-set

library - librerias estandar dev c++



¿No hay especializaciones de std:: hash para contenedores estándar? (2)

No es una respuesta, sino alguna información útil. El borrador de febrero del estándar C ++ 11 especifica que std::hash está especializado para estos tipos:

  • error_code § 19.5.5
  • bitset<N> § 20.5.3
  • unique_ptr<T, D> § 20.7.2.36
  • shared_ptr<T, D> § 20.7.2.36
  • type_index § 20.13.4
  • string § 21.6
  • u16string § 21.6
  • u32string § 21.6
  • wstring § 21.6
  • vector<bool, Allocator> § 23.3.8
  • thread::id § 30.3.1.1

Y todos estos tipos: § 20.8.12.

template <> struct hash<bool>; template <> struct hash<char>; template <> struct hash<signed char>; template <> struct hash<unsigned char>; template <> struct hash<char16_t>; template <> struct hash<char32_t>; template <> struct hash<wchar_t>; template <> struct hash<short>; template <> struct hash<unsigned short>; template <> struct hash<int>; template <> struct hash<unsigned int>; template <> struct hash<long>; template <> struct hash<long long>; template <> struct hash<unsigned long>; template <> struct hash<unsigned long long>; template <> struct hash<float>; template <> struct hash<double>; template <> struct hash<long double>; template<class T> struct hash<T*>;

Me sorprendí un poco al no poder usar simplemente un

std::unordered_set<std::array<int, 16> > test;

porque no parece haber una especialización std::hash para std::array s. ¿Porqué es eso? ¿O simplemente no lo encontré? Si no hay ninguno, ¿se puede simplificar el siguiente intento de implementación?

namespace std { template<typename T, size_t N> struct hash<array<T, N> > { typedef array<T, N> argument_type; typedef size_t result_type; result_type operator()(const argument_type& a) const { hash<T> hasher; result_type h = 0; for (result_type i = 0; i < N; ++i) { h = h * 31 + hasher(a[i]); } return h; } }; }

Realmente siento que esto debería ser de alguna manera parte de la biblioteca estándar.


No estoy seguro de por qué la biblioteca estándar no ha incluido esto, pero Boost tiene hash para todo tipo de cosas compuestas de tipos hashable. La función clave para esto es hash_combine , que puede copiar desde boost/functional/hash/hash.hpp .

Usando hash_combine , Boost deriva un range_hash (simplemente combinando los hashes de cada elemento de un rango), así como los hashers de pares y tuplas. El range_hash a su vez se puede utilizar para hash cualquier contenedor iterable.