正如指出的使用的std ::的unique_ptr的一个std :: unordered_set,这是不容易找到一个指针T*
中std::unordered_set<std::unique_ptr<T>>
。在C ++ 20之前,我们被迫构造的实例std::unique_ptr<T>
。
由于对无序容器建议(http://wg21.link/P0919r3和http://wg21.link/p1690r1)进行了异构查找,因此在C ++ 20中可以解决此问题。但是可用的解决方案对我来说显得很笨拙(即使按照C ++标准)。似乎我需要从头实现而不是一个,而是两个函子(用于透明哈希和透明比较):
template<class T>
struct Equal {
using is_transparent = void;
bool operator()(const std::unique_ptr<T>& lhs, const std::unique_ptr<T>& rhs) const {
return lhs == rhs;
}
bool operator()(const std::unique_ptr<T>& lhs, const T* rhs) const {
return lhs.get() == rhs;
}
bool operator()(const T* lhs, const std::unique_ptr<T>& rhs) const {
return lhs == rhs.get();
}
};
template<class T>
struct Hash {
using is_transparent = void;
size_t operator()(const std::unique_ptr<T>& ptr) const {
return std::hash<const T*>()(ptr.get());
}
size_t operator()(const T* ptr) const {
return std::hash<const T*>()(ptr);
}
};
template<class T>
using UnorderedSetOfUniquePtrs = std::unordered_set<std::unique_ptr<T>, Hash<T>, Equal<T>>;
演示:https : //gcc.godbolt.org/z/bqx714(该建议目前仅在MSVC中实现)。
这可以工作,但看起来像很多样板。我想念什么吗?有没有办法使用IDK,也许是一些标准的透明哈希器或相等比较器?我看到它std::equal_to<void>
是透明的,但是我不能直接使用它。也许有一个偷偷摸摸的方式来定义unique_ptr<T> -> T*
隐式转换“仅适用于此类UnorderedSetOfUniquePtrs
”?欢迎您提出您的想法。
您可以将详细程度转换为std :: to_address(感谢@Caleth指出)和现存的std::hash
,后者专门用于std::unique_ptr
基于原始地址返回哈希(感谢@Mikhail的提示)。然后,使用成员函数模板实现哈希和相等类型(请注意,您不再需要将类型本身作为模板):
struct Equal {
using is_transparent = void;
template<class U, class S>
bool operator()(const U& lhs, const S& rhs) const {
return std::to_address(lhs) == std::to_address(rhs);
}
};
struct Hash {
using is_transparent = void;
template<class U>
size_t operator()(const U& ptr) const {
return std::hash<U>{}();
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句