c++ 在shared_ptr的unordered_set中查找值

pftdvrlh  于 10个月前  发布在  其他
关注(0)|答案(2)|浏览(144)

我想在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

字符串
我试过跟踪,但还是不行。

namespace std {
  template <> struct hash<IntPtr> {
    size_t operator()(const IntPtr& x) const noexcept {
      return std::hash<int>()(*x);
    }
  };
}


有办法让它工作吗?

r55awzrz

r55awzrz1#

你存储了一个指向整数的 * 指针 *。当你在集合中查找元素时,你不是在比较(指向的)整数,而是指针本身。
当你分配一个 new 指针给一个 new integer对象进行搜索时,它不会比较相等,因为它是一个不同的integer对象(即使它存储了相同的值)。
您可以选择:
1.不要在集合中存储指向整数的指针,直接存储整数即可。
然后,您的键是42,搜索42将找到它,因为整数是按值进行比较的
1.存储指针并使用自定义哈希和比较器来比较 * 指向的整数 * 而不是指针。
你不应该(试图)用你的哈希专门化来污染std命名空间,而且这是不够的(哈希用于桶查找,但键仍然会与桶内的KeyEqual进行比较)。只需为你的容器指定它们。
示例代码#2:

#include <cassert>
#include <memory>
#include <unordered_set>

namespace 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());
}

字符串

svujldwt

svujldwt2#

根据here
请注意,shared_ptr的比较运算符只是比较指针值;并不比较指向的实际对象。
所以found只有在shared_ptr指向同一个对象时才为真:

typedef std::shared_ptr<int> IntPtr;

std::unordered_set<IntPtr> s;
IntPtr p = std::make_shared<int>(42);
s.insert(p);

bool found = s.find(p) != s.end();
cout<<std::boolalpha<<found<<endl; // true

字符串

相关问题