所以我有使用的代码std::weak_ptr
并将它们维护在std::set
,而且效果很好——并且在过去的五七年里一直有效。最近我想我应该在一个std::unordered_set
(嗯,实际上在一个f14::F14ValueSet
)为此,我需要它的哈希值。截至目前,还没有std::hash<std::weak_ptr>
,那么我应该做什么呢?
答案似乎是“只是散列控制块”,正如这个问题和答复所暗示的那样:为什么在 C++0x 中没有为 std::weak_ptr 定义 std::hash ? https://stackoverflow.com/questions/4750504/why-was-stdhash-not-defined-for-stdweak-ptr-in-c0x,但是我如何访问控制块呢?在glibc中,它位于__weak_ptr<>::_M_refcount._M_pi->
但这是私有的(并且是特定于实现的)。我还可以做些什么?
一个答案是“等等”:也许有一天会有一个标准owner_hash() for std::weak_ptr http://open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1901r1.html,但我更喜欢现在可用的东西。
制作你自己的增强弱指针。
它存储一个哈希值,并支持==
基于owner_before()
.
You must使这些来自shared_ptr
s,作为没有强引用的弱 ptr,无法进行哈希处理以匹配其所有者;这可能会创建两个比较相等但散列不同的增强弱指针。
template<class T>
struct my_weak_ptr {
// weak ptr API clone goes here. lock() etc.
// different ctor:
my_weak_ptr(std::shared_ptr<T>const& sp){
if(!sp) return;
ptr=sp;
hash = std::hash<T*>{}(sp.get());
}
std::size_t getHash()const{return hash;}
friend bool operator<(my_weak_ptr const& lhs, my_weak_ptr const& rhs){
return lhs.owner_before(rhs);
}
friend bool operator!=(my_weak_ptr const& lhs, my_weak_ptr const& rhs){
return lhs<rhs || rhs<lhs;
}
friend bool operator==(my_weak_ptr const& lhs, my_weak_ptr const& rhs){
return !(lhs!=rhs);
}
private:
std::weak_ptr<T> ptr;
std::size_t hash=0;
};
它们具有稳定、合理的哈希值。虽然回收的对象指针会导致哈希冲突,但只要它们不共享控制块,它们就不会相等。
namespace std{template<class T>struct hash<some_ns::my_weak_ptr<T>>{
std::size_t operator()(my_weak_ptr<T> const& wp)const{return wp.getHash();}
};}
一个警告:使用别名构造函数可能会导致病态结果。因为相等性基于控制块相等性,而不是指针值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)