所以我尝试实现 - 正如Yakk所建议的 - Adam Nevraumont在他对这个问题的回答中提出的一种继承哈希弱指针实现,包括公共接口。如果我做错了什么,有人可以发表评论吗?
template<class T>
struct HashableWeakPointer : protected std::weak_ptr<T>
{
public:
class Hash
{
public:
size_t operator()(HashableWeakPointer const & hashableWeakPointer) const
{
return hashableWeakPointer.getHash();
}
};
HashableWeakPointer(std::shared_ptr<T> const & sp)
: std::weak_ptr<T>(sp)
, hash(0)
{
if (static_cast<bool>(sp))
{
hash = std::hash<T*>{}(sp.get());
}
}
void reset() noexcept
{
std::weak_ptr<T>::reset();
hash = 0;
}
void swap(HashableWeakPointer & r) noexcept
{
std::weak_ptr<T>::swap(r);
std::swap(hash, r.hash);
}
using std::weak_ptr<T>::use_count;
using std::weak_ptr<T>::expired;
using std::weak_ptr<T>::lock;
template< class Y >
bool owner_before( const HashableWeakPointer<Y>& other ) const noexcept
{
return std::weak_ptr<T>::owner_before(static_cast<std::weak_ptr<Y>>(other));
}
template< class Y >
bool owner_before( const std::shared_ptr<Y>& other ) const noexcept
{
return std::weak_ptr<T>::owner_before(other);
}
std::size_t getHash() const noexcept
{
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);
}
friend std::ostream & operator<<(std::ostream & os, const HashableWeakPointer& dt)
{
os << "<" << dt.lock().get() << "," << dt.hash << ">";
return os;
}
private:
std::size_t hash;
};
关于使用,以下是一个小样例代码
#include <iostream>
#include <memory>
#include <unordered_map>
typedef unsigned KeyValueType;
typedef HashableWeakPointer<KeyValueType> KeyType;
typedef unsigned ValueType;
typedef std::unordered_map<KeyType, ValueType, KeyType::Hash> MapType;
int main()
{
std::shared_ptr<KeyValueType> sharedPointer = std::make_shared<KeyValueType>(17);
ValueType const value = 89;
MapType map;
std::pair<MapType::iterator,bool> const inserted = map.insert({sharedPointer, value});
if (not inserted.second)
{
std::cerr << "Element for value " << value << " already existed." << std::endl;
}
for (MapType::value_type const & entry : map )
{
std::cout << "Key:[" << entry.first << "] Value:[" << entry.second << "]" << std::endl;
}
return 0;
}
这将为我输出[使用64位的size_t
]:
Key:[<0x1ea4b2817f0,2105794893808>] Value:[89]
可以看到,值指针被用作哈希键[2105794893808 = 0x1ea4b2817f0]。