Para admitir tipos de clave definidos por el usuario en std::unordered_set<Key>y std::unordered_map<Key, Value>
uno tiene que proporcionar operator==(Key, Key)un functor hash:
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 solo std::unordered_set<X>
con un hash predeterminado para el tipo X, como para los tipos que vienen junto con el compilador y la biblioteca. Después de consultar
- Borrador de la norma C ++ N3242 §20.8.12 [unord.hash] y §17.6.3.4 [hash.requirements],
- Impulsar sin ordenar
- g ++
include\c++\4.7.0\bits\functional_hash.h - VC10
include\xfunctional - varias preguntas relacionadas en Stack Overflow
parece 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
}
Dado que el soporte del compilador para C ++ 11 aún es experimental --- no probé Clang ---, estas son mis preguntas:
¿Es legal agregar tal especialización al espacio de nombres
std? Tengo sentimientos encontrados respecto de eso.¿Cuál de las
std::hash<X>::operator()versiones, si alguna, es compatible con el estándar C ++ 11?¿Existe una forma portátil de hacerlo?
std::hash(a diferencia de otras cosas en el stdespacio de nombres) ; Tómelo con un grano de sal.
operator==(const Key, const Key)