Boost C++;:作为无序集共享的ptr';s键

Boost C++;:作为无序集共享的ptr';s键,boost,shared-ptr,hash-function,unordered-set,Boost,Shared Ptr,Hash Function,Unordered Set,考虑以下代码 #include <boost/unordered_set.hpp> #include <boost/shared_ptr.hpp> #include <boost/make_shared.hpp> int main() { boost::unordered_set<int> s; s.insert(5); s.insert(5); // s.size() == 1 boost::unor

考虑以下代码

#include <boost/unordered_set.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

int main()
{
    boost::unordered_set<int> s;
    s.insert(5);
    s.insert(5);
    // s.size() == 1 

    boost::unordered_set<boost::shared_ptr<int> > s2;
    s2.insert(boost::make_shared<int>(5));
    s2.insert(boost::make_shared<int>(5));
    // s2.size() == 2
}
#包括
#包括
#包括
int main()
{
boost::无序的集合;
s、 插入(5);
s、 插入(5);
//s.大小()==1
boost::无序_集s2;
s2.插入(boost::使_共享(5));
s2.插入(boost::使_共享(5));
//s2.size()==2
}
问题是:为什么s2的大小是2而不是1?我很确定这一定和哈希函数有关。我试着查看boost文档,并在没有运气的情况下玩弄hash函数


想法?

使共享
分配一个新的
int
,并在其周围包装一个
共享
。这意味着您的两个
shared_ptr
s指向不同的内存,并且由于您正在创建一个以指针值为键的哈希表,所以它们是不同的键

出于同样的原因,这将导致大小为2:

boost::unordered_set<int *> s3;
s3.insert(new int(5));
s3.insert(new int(5));
assert(s3.size() == 2);
然而,这可能是一个坏主意,原因如下:

  • 您遇到了一个令人困惑的情况,
    x!=y
    但是
    s4[x]
    s4[y]
    是相同的
  • 如果有人更改哈希键所指向的值,您的哈希将中断!即:

    boost::shared_ptr<int> tmp(new int(42));
    s4[tmp] = 42;
    *tmp = 24; // UNDEFINED BEHAVIOR
    
    boost::shared_ptr tmp(新int(42));
    s4[tmp]=42;
    *tmp=24;//未定义的行为
    

  • 通常,对于哈希函数,您希望密钥是不可变的;无论以后发生什么,它都会比较相同。如果您使用的是指针,您通常希望指针标识是匹配的,如
    extra\u info\u hash[&some\u object]=…
    ;这通常会映射到相同的散列值,无论某个对象的成员是什么。如果插入后键是可变的,那么实际上很容易这样做,从而导致散列中的行为未定义。

    正如您所发现的,插入到
    s2
    中的两个对象是不同的

    请注意,当然,在Boost Right中。所以我还是应该能够通过使用(智能)指针来实现相同的语义?这意味着通过以某种特定方式定义哈希函数,大小将是1而不是2。我该怎么做?
    boost::shared_ptr<int> tmp(new int(42));
    s4[tmp] = 42;
    *tmp = 24; // UNDEFINED BEHAVIOR