Deq*_*ing 3 c++ shared-ptr unordered-set
我想在unordered_set中找到一个值,但是失败了:
typedef std::shared_ptr<int> IntPtr;
std::unordered_set<IntPtr> s;
s.insert(std::make_shared<int>(42));
bool found = s.find(std::make_shared<int>(42)) != s.end();
cout<<std::boolalpha<<found<<endl; // false
Run Code Online (Sandbox Code Playgroud)
曾尝试过但仍然没有工作.
namespace std {
template <> struct hash<IntPtr> {
size_t operator()(const IntPtr& x) const noexcept {
return std::hash<int>()(*x);
}
};
}
Run Code Online (Sandbox Code Playgroud)
知道如何让它有效吗?
您存储了一个指向整数的指针.当你在集合中查找项目时,你不是在比较(指向的)整数,而是指针本身.
当您为搜索分配新的整数对象的新指针时,它将不会比较相等,因为它是一个不同的整数对象(即使它存储相同的值).
你的选择是:
不要在集合中存储指向整数的指针,只需直接存储整数.
然后,你的密钥是42,并且搜索42将找到它,因为整数按值进行比较
存储指针并使用自定义散列和比较器来比较指向的整数而不是指针.
您不应该(尝试)std使用您的哈希特化来污染命名空间,并且它无论如何都不够(哈希用于存储桶查找,但仍然会将存储桶内的密钥进行比较KeyEqual).只需为容器指定它们即可.
#2的示例代码:
#include <cassert>
#include <memory>
#include <unordered_set>
struct Deref {
struct Hash {
template <typename T>
std::size_t operator() (std::shared_ptr<T> const &p) const {
return std::hash<T>()(*p);
}
};
struct Compare {
template <typename T>
size_t operator() (std::shared_ptr<T> const &a,
std::shared_ptr<T> const &b) const {
return *a == *b;
}
};
};
int main() {
std::unordered_set<std::shared_ptr<int>> sp;
auto p = std::make_shared<int>(42);
sp.insert(p);
assert(sp.find(p) != sp.end()); // same pointer works
assert(sp.find(std::make_shared<int>(42)) == sp.end()); // same value doesn't
// with the correct hash & key comparison, both work
std::unordered_set<std::shared_ptr<int>, Deref::Hash, Deref::Compare> spd;
spd.insert(p);
assert(spd.find(p) != spd.end());
assert(spd.find(std::make_shared<int>(42)) != spd.end());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1625 次 |
| 最近记录: |