Section: 20.3.2.2 [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.