This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD status.

### 1406. Support hashing smart-pointers based on owner

Section: 20.11.3 [util.smartptr.shared] Status: NAD Submitter: Japan Opened: 2010-08-25 Last modified: 2019-02-26

Priority: Not Prioritized

View all other issues in [util.smartptr.shared].

View all issues with NAD status.

Discussion:

Addresses JP-5

Hash support based on ownership sharing should be supplied for `shared_ptr` and `weak_ptr`. For two `shared_ptr` objects `p` and `q`, two distinct equivalence relations can be defined. One is based on equivalence of pointer values, which is derived from the expression `p.get() == q.get()` (hereafter called address based equivalence relation), the other is based on equivalence of ownership sharing, which is derived from the expression `!p.owner_before(q) && !q.owner_before(p)` (hereafter called ownership-based equivalence relation). These two equivalence relations are independent in general. For example, a `shared_ptr` object created by the constructor of the signature `shared_ptr(shared_ptr<U> const &, T *)` could reveal a difference between these two relations. Therefore, hash support based on each equivalence relation should be supplied for `shared_ptr`. However, while the standard library provides the hash support for address-based one (20.9.11.6 paragraph 2), it lacks the hash support for ownership-based one. In addition, associative containers work well in combination with the `shared_ptr`'s ownership-based comparison but unordered associative containers don't. This is inconsistent.

For the case of `weak_ptr`, hash support for the ownership based equivalence relation can be safely defined on `weak_ptr`s, and even on expired ones. The absence of hash support for the ownership-based equivalence relation is fatal, especially for expired `weak_ptr`s. And the absence of such hash support precludes some quite effective use-cases, e.g. erasing the `unordered_map` entry of an expired `weak_ptr` key from a customized deleter supplied to `shared_ptr`s.

Hash support for the ownership-based equivalence relation cannot be provided by any user-defined manner because information about ownership sharing is not available to users at all. Therefore, the only way to provide ownership-based hash support is to offer it intrusively by the standard library.

As far as we know, such hash support is implementable. Typical implementation of such hash function could return the hash value of the pointer of the counter object that is internally managed by `shared_ptr` and `weak_ptr`.

[2010 Rapperswil:]

> No consensus to make this change at this time.

[LEWG Kona 2017]

Recommend NAD: Needs a paper. Feature. Exposing an implementation detail (indirectly observable via hash).

Proposed resolution:

Add the following non-static member functions to `shared_ptr` and `weak_ptr` class template;

Update [util.smartptr.shared], 20.9.11.2 paragraph 1

    namespace std{
    template<class T> class shared_ptr {
    public:
    ...
      size_t owner_hash() const;
    ...
    };
    }

Update [util.smartptr.weak], 20.9.11.3 paragraph 1

    namespace std{
    template<class T> class weak_ptr {
    public:
    ...
      size_t owner_hash() const;
    ...
    };
    }

These functions satisfy the following requirements. Let `p` and `q` be objects of either `shared_ptr` or `weak_ptr`, `H` be a hypothetical function object type that satisfies the hash requirements ([hash.requirements], 20.2.4) and `h` be an object of the type `H`. The expression `p.owner_hash()` behaves as if it were equivalent to the expression `h(p)`. In addition, `h(p) == h(q)` must become `true` if `p` and `q` share ownership.