para soportar tipos de claves definidas por el usuario en std::unordered_set<Key>
y std::unordered_map<Key, Value>
uno tiene que proporcionar operator==(Key, Key)
y un funtor de hash:Cómo especializar std :: hash <Key> :: operator() para tipo definido por el usuario en contenedores desordenados?
struct X { int id; /* ... */ };
bool operator==(X a, X b) { return a.id == b.id; }
struct MyHash {
size_t operator()(const X& x) const { return std::hash<int>()(x.id); }
};
std::unordered_set<X, MyHash> s;
Sería más conveniente escribir simplemente std::unordered_set<X>
con un hash predeterminado para el tipo X
, me gusta para los tipos que vienen junto con el compilador y la biblioteca. Después de consultar
- C++ estándar Draft N3242 §20.8.12 [unord.hash] y §17.6.3.4 [hash.requirements],
- Boost.Unordered
- g ++
include\c++\4.7.0\bits\functional_hash.h
- VC10
include\xfunctional
- diversos related question s en desbordamiento de pila
se ems posible especializarse std::hash<X>::operator()
:
namespace std { // argh!
template <>
inline size_t
hash<X>::operator()(const X& x) const { return hash<int>()(x.id); } // works for MS VC10, but not for g++
// or
// hash<X>::operator()(X x) const { return hash<int>()(x.id); } // works for g++ 4.7, but not for VC10
}
apoyo compilador para C++ Dada 11 todavía es experimental --- Yo no probar Clang ---, estas son mis preguntas:
¿Es legal para agregar tal especialización al espacio de nombres
std
? Tengo sentimientos encontrados respecto de eso.¿Cuál de las versiones de
std::hash<X>::operator()
, si las hay, cumple con el estándar C++ 11?¿Hay una manera portátil de hacerlo?
con GCC 4.7.2, tenía que proporcionar un == mundial 'operador (clave const, clave const) ' –