元素存储在 set 或者 unordered_set 是不可变的。如果更改存储在 set 这可能会导致设备无法正常工作。但是,这在存储时是否包括指向的对象 shared_ptr 在一组?

据,直到...为止 set 担心它使用 less() 比较两个对象。如果指向的对象发生变化或引用计数发生变化,结果不应改变。所以我明白拥有一套是完全安全的 shared_ptr 并修改所指向的对象。

然而,自从 unordered_set 用途 hash() 计算其元素的哈希值,相当于调用 hash() 在 a 所指向的对象上 shared_ptr, ,修改指向的对象会给我们带来麻烦。

它是否正确?

有帮助吗?

解决方案

hash() 对于智能指针来说相当于 hash() 为指针值,但是 hash() 因为指针值仅取决于指针,而不取决于指针对象。因此您可以安全地修改容器中的对象 - 哈希函数结果不会改变。

其他提示

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

STL集合使用红黑树作为实现-(这样做的原因是为了有统一的插入时间;没有像散列映射那样的线性最坏情况);如果你改变了键,那么树就不再平衡了;该实现使用operator<和operator==,而不是哈希。

无序集合使用桶哈希表作为实现;这里使用哈希值;更改键意味着该条目将不再属于哈希表的同一桶。

shared_ptr的operator<和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); }
  };

在 gcc stl 上:

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top