Assuming a custom HashableWeakPointer as proposed in this question I would like to ask for further clarification of statements written in an answer to that question.
template<class T>
struct HashableWeakPointer {
// weak ptr API clone goes here. lock() etc.
// different ctor:
HashableWeakPointer (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<(HashableWeakPointer const& lhs, HashableWeakPointer const& rhs){
return lhs.owner_before(rhs);
}
friend bool operator!=(HashableWeakPointer const& lhs, HashableWeakPointer const& rhs){
return lhs<rhs || rhs<lhs;
}
friend bool operator==(HashableWeakPointer const& lhs, HashableWeakPointer const& rhs){
return !(lhs!=rhs);
}
private:
std::weak_ptr<T> ptr;
std::size_t hash=0;
};
- "While a recycled object pointer results in a hash collision, so long as they don't share control blocks they won't be equal."
And as the control block of a weak_ptr is not freed until the last referencing weak_ptr [and shared_ptr...] to that instance is destroyed, this should be save with regard to the cited statement - right?
- "One warning: Use of aliasing constructor could result in pathological results. As equality is based on control block equality, not pointer value."
But this is not a deficiency of your proposed solution, but rather a question of one's definition of what it means for two weak_ptrs to be equal, isn't it?
Would the following distinguish aliasing smart pointers with somewhat less pathological results?
friend bool operator<(HashableWeakPointer const& lhs, HashableWeakPointer const& rhs)
{
return lhs.owner_before(rhs) || ((not rhs.owner_before(lhs)) && (lhs.hash < rhs.hash));
}
where the second part is only evaluated if the first is false, which thus would mean for (lhs.hash < rhs.hash) being relevant it must (not lhs.owner_before(rhs)) && ((not rhs.owner_before(lhs)) evaluate to true, i.e. the same owner be referenced?