978. Hashing smart pointers

Section: 23.14.15 [unord.hash] Status: C++11 Submitter: Alisdair Meredith Opened: 2009-02-02 Last modified: 2016-02-10

Priority: Not Prioritized

View other active issues in [unord.hash].

View all other issues in [unord.hash].

View all issues with C++11 status.

Discussion:

Addresses UK 208

I don't see an open issue on supporting std::hash for smart pointers (unique_ptr and shared_ptr at least).

It seems reasonable to at least expect support for the smart pointers, especially as they support comparison for use in ordered associative containers.

[ Batavia (2009-05): ]

Howard points out that the client can always supply a custom hash function.

Alisdair replies that the smart pointer classes are highly likely to be frequently used as hash keys.

Bill would prefer to be conservative.

Alisdair mentions that this issue may also be viewed as a subissue or duplicate of issue 1025.

Move to Open, and recommend the issue be deferred until after the next Committee Draft is issued.

[ 2009-05-31 Peter adds: ]

Howard points out that the client can always supply a custom hash function.

Not entirely true. The client cannot supply the function that hashes the address of the control block (the equivalent of the old operator<, now proudly carrying the awkward name of 'owner_before'). Only the implementation can do that, not necessarily via specializing hash<>, of course.

This hash function makes sense in certain situations for shared_ptr (when one needs to switch from set/map using ownership ordering to unordered_set/map) and is the only hash function that makes sense for weak_ptr.

[ 2009-07-28 Alisdair provides wording. ]

[ 2009-10 Santa Cruz: ]

Move to Ready.

[ 2009-11-16 Moved from Ready to Open: ]

Pete writes:

As far as I can see, "...suitable for using this type as key in unordered associative containers..." doesn't define any semantics. It's advice to the reader, and if it's present at all it should be in a note. But we have far too much of this sort of editorial commentary as it is.

And in the resolution of 978 it's clearly wrong: it says that if there is no hash specialization available for D::pointer, the implementation may provide hash<unique_ptr<T,D>> if the result is not suitable for use in unordered containers.

Howard writes:

Is this a request to pull 978 from Ready?

Barry writes:

I read this as more than a request. The PE says it's wrong, so it can't be Ready.

[ 2010-01-31 Alisdair: related to 1245 and 1182. ]

[ 2010-02-08 Beman updates wording. ]

[ 2010-02-09 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]

Proposed resolution:

Add the following declarations to the synopsis of <memory> in 23.10 [memory]

// [util.smartptr.hash] hash support
template <class T> struct hash;
template <class T, class D> struct hash<unique_ptr<T,D>>;
template <class T> struct hash<shared_ptr<T>>;

Add a new subclause under [util.smartptr] called hash support

hash support [util.smartptr.hash]

template <class T, class D> struct hash<unique_ptr<T,D>>;

Specialization meeting the requirements of class template hash (23.14.15 [unord.hash]). For an object p of type UP, where UP is a type unique_ptr<T,D>, hash<UP>()(p) shall evaluate to the same value as hash<typename UP::pointer>()(p.get()). The specialization hash<typename UP::pointer> is required to be well-formed.

template <class T> struct hash<shared_ptr<T>>;

Specialization meeting the requirements of class template hash (23.14.15 [unord.hash]). For an object p of type shared_ptr<T>, hash<shared_ptr<T>>()(p) shall evaluate to the same value as hash<T*>()(p.get()).