在(unordered_)集合中修改shared_ptr是否安全?

Is it safe to modify shared_ptr in an (unordered_)set?

本文关键字:ptr shared 是否 修改 安全 unordered 集合      更新时间:2023-10-16

存储在setunordered_set中的元素是不可变的。如果一个人改变了存储在set中的元素,这可能会导致该集合不再正常工作。但是,这是否包括在集合中存储shared_ptr时指向的对象?

set而言,它使用less()来比较两个对象。如果指向的对象发生变化或refcount发生变化,结果不应改变。因此,我可以理解,拥有一组shared_ptr并修改指向对象是完全安全的。

然而,由于unordered_set使用hash()来计算其元素的哈希值,这相当于在shared_ptr的指向对象上调用hash(),因此修改指向对象会给我们带来麻烦。

正确吗?

智能指针的hash()相当于指针值的hash(),但指针值的hash()只取决于指针,而不取决于被指针。所以你可以安全地修改容器中的对象——哈希函数的结果不会被改变。

shared_ptr<T>的哈希函数不依赖于它所指向的实例的状态。因此,您可以安全地修改状态,而不会使容器失效。

STL set使用红黑树作为实现-(这样做的原因是有统一的插入时间;没有线性最坏的情况,如在hash map);如果你改变了键,那么树就不再平衡;实现使用operator<操作符>

unordered set使用bucket哈希表作为实现;这里使用哈希;更改键意味着该条目将不再属于哈希表的同一桶。

要的operator

共享PTR的哈希值将只是包装指针的数值

  template<typename _Tp, _Lock_policy _Lp>
    struct hash<__shared_ptr<_Tp, _Lp>>
    : public std::unary_function<__shared_ptr<_Tp, _Lp>, size_t>
    {
      size_t
      operator()(const __shared_ptr<_Tp, _Lp>& __s) const
      { return std::hash<_Tp*>()(__s.get()); }
    };
template<typename _Tp>
  struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
  {
    size_t
    operator()(_Tp* __p) const
    { return reinterpret_cast<size_t>(__p); }
  };

c++/<version>/map inculudes c++/<version>/bits/stl_set.h 
c++/<version>/bits/stl_set.h
  template<typename _Key, typename _Compare = std::less<_Key>,
           typename _Alloc = std::allocator<_Key> >
    class set
    {
   typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
                    key_compare, _Key_alloc_type> _Rep_type;
   _Rep_type _M_t;  // Red-black tree representing set.
c++/<version>/bits/tree.h
    <here red black tre _Rb_tree class is implemented>
 c++/<version>/unordered_set includs c++/<version>/bits/unordered_set.h this one uses hashtable in c++/<version>/bits/hashtable.h