¿Cómo calcular el hash de std::weak_ptr?
Tengo un código que usa std::weak_ptr
y los mantiene en un std::set
, y eso funciona bien, y ha funcionado durante los últimos 5 o 7 años. Recientemente pensé en jugar con ellos en un std::unordered_set
(bueno, en realidad en un f14::F14ValueSet
) y para eso, necesitaría un hash de esto. Hasta ahora, no hay std::hash<std::weak_ptr>
, ¿qué debería hacer en su lugar?
La respuesta parece ser “solo hashear el bloque de control”, como se sugiere en esta pregunta y respuesta: https://stackoverflow.com/questions/4750504/why-was-stdhash-not-defined-for-stdweak-ptr-in-c0x, pero ¿cómo puedo acceder al bloque de control? En glibc, se encuentra en __weak_ptr<>::_M_refcount._M_pi->
, pero eso es privado (y específico de la implementación). ¿Qué más puedo hacer?
Una respuesta es “solo espera”: quizás algún día habrá un owner_hash()
estándar para std::weak_ptr
, pero preferiría algo disponible ahora.
davy.ai
Por el momento, no hay un
std::hash<std::weak_ptr>
integrado en C++, lo cual es necesario cuando se usan en un conjunto no ordenado o tabla de hash. Sin embargo, una solución posible es simplemente hacer hash del bloque de control, como sugieren algunos foros en línea. Pero acceder al bloque de control es privado y específico de la implementación, por lo que puede que no sea la mejor solución.Otra opción podría ser definir una función de hash personalizada para
std::weak_ptr
usando su métodolock()
para extraer un puntero compartido y luego usar su funciónhash
. Aquí hay un ejemplo de implementación:c++
struct WeakPtrHash {
template <typename t="">
std::size_t operator()(const std::weak_ptr<t>& wp) const {
if (auto sp = wp.lock()) {
return std::hash<><t>>{}(sp);
} else {
return 0;
}
}
};
Esta implementación verifica si el puntero débil aún es válido y luego extrae un puntero compartido de él. Finalmente, usa la función estándar
std::hash<std::shared_ptr>
para calcular el valor hash.En general, mientras se espera un
owner_hash()
estándar parastd::weak_ptr
, definir una función hash personalizada parece ser la mejor opción disponible por ahora.