<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 978: Hashing smart pointers</title>
<meta property="og:title" content="Issue 978: Hashing smart pointers">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue978.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#C++11">C++11</a> status.</em></p>
<h3 id="978"><a href="lwg-defects.html#978">978</a>. Hashing smart pointers</h3>
<p><b>Section:</b> 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a> <b>Status:</b> <a href="lwg-active.html#C++11">C++11</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2009-02-02 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#unord.hash">issues</a> in [unord.hash].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#C++11">C++11</a> status.</p>
<p><b>Discussion:</b></p>
<p><b>Addresses UK 208</b></p>
<p>
I don't see an open issue on supporting <code>std::hash</code> for smart pointers
(<code>unique_ptr</code> and <code>shared_ptr</code> at least).
</p>
<p>
It seems reasonable to at least expect support for the smart
pointers, especially as they support comparison for use in ordered
associative containers.
</p>

<p><i>[
Batavia (2009-05):
]</i></p>

<blockquote>
<p>
Howard points out that the client can always supply a custom hash function.
</p>
<p>
Alisdair replies that the smart pointer classes are highly likely
to be frequently used as hash keys.
</p>
<p>
Bill would prefer to be conservative.
</p>
<p>
Alisdair mentions that this issue may also be viewed as a subissue or
duplicate of issue <a href="lwg-closed.html#1025" title="The library should provide more specializations for std::hash (Status: NAD Future)">1025</a><sup><a href="https://cplusplus.github.io/LWG/issue1025" title="Latest snapshot">(i)</a></sup>.
</p>
<p>
Move to Open, and recommend the issue be deferred until after the next
Committee Draft is issued.
</p>
</blockquote>

<p><i>[
2009-05-31 Peter adds:
]</i></p>


<blockquote>
<blockquote><p>
Howard points out that the client can always supply a custom hash function.
</p></blockquote>
<p>
Not entirely true. The client cannot supply the function that hashes the
address of the control block (the equivalent of the old <code>operator&lt;</code>, now
proudly carrying the awkward name of '<code>owner_before</code>'). Only the
implementation can do that, not necessarily via specializing <code>hash&lt;&gt;</code>, of
course.
</p>
<p>
This hash function makes sense in certain situations for <code>shared_ptr</code>
(when one needs to switch from <code>set/map</code> using ownership ordering to
<code>unordered_set/map</code>) and is the only hash function that makes sense for
<code>weak_ptr</code>.
</p>
</blockquote>

<p><i>[
2009-07-28 Alisdair provides wording.
]</i></p>


<p><i>[
2009-10 Santa Cruz:
]</i></p>


<blockquote><p>
Move to Ready.
</p></blockquote>

<p><i>[
2009-11-16 Moved from Ready to Open:
]</i></p>


<blockquote>
<p>
Pete writes:
</p>
<blockquote>
<p>
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.
</p>
<p>
And in the resolution of 978 it's clearly wrong: it says that if there is no
hash specialization available for <code>D::pointer</code>, the implementation may provide
<code>hash&lt;unique_ptr&lt;T,D&gt;&gt;</code> if the result is not suitable for use in unordered
containers.
</p>
</blockquote>

<p>
Howard writes:
</p>

<blockquote><p>
Is this a request to pull 978 from Ready?
</p></blockquote>

<p>
Barry writes:
</p>
<blockquote>
<p>
I read this as more than a request. The PE says it's wrong, so it can't be
Ready.
</p>
</blockquote>

</blockquote>

<p><i>[
2010-01-31 Alisdair: related to <a href="lwg-defects.html#1245" title="std::hash&lt;string&gt; &amp; co (Status: C++11)">1245</a><sup><a href="https://cplusplus.github.io/LWG/issue1245" title="Latest snapshot">(i)</a></sup> and <a href="lwg-defects.html#1182" title="Unfortunate hash dependencies (Status: C++11)">1182</a><sup><a href="https://cplusplus.github.io/LWG/issue1182" title="Latest snapshot">(i)</a></sup>.
]</i></p>


<p><i>[
2010-02-08 Beman updates wording.
]</i></p>


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




<p id="res-978"><b>Proposed resolution:</b></p>

<p><i>Add the following declarations to the synopsis of <code>&lt;memory&gt;</code> in 
20.2 <a href="https://wg21.link/memory">[memory]</a> </i></p>

<blockquote>
<pre><ins>// [util.smartptr.hash] hash support
template &lt;class T&gt; struct hash;
template &lt;class T, class D&gt; struct hash&lt;unique_ptr&lt;T,D&gt;&gt;;
template &lt;class T&gt; struct hash&lt;shared_ptr&lt;T&gt;&gt;;</ins></pre>
</blockquote>

<p><i>Add a new subclause under  [util.smartptr] called hash support </i></p>

<blockquote>
<h3><ins>hash support [util.smartptr.hash]</ins></h3>

<pre><ins>template &lt;class T, class D&gt; struct hash&lt;unique_ptr&lt;T,D&gt;&gt;;</ins></pre>

<blockquote>
<p><ins>
Specialization meeting the requirements of class template <code>hash</code> (22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a>). For an object <code>p</code> of type <code>UP</code>, where
<code>UP</code> is a type <code>unique_ptr&lt;T,D&gt;</code>,
<code>hash&lt;UP&gt;()(p)</code> shall evaluate to the same value as
<code>hash&lt;typename UP::pointer&gt;()(p.get())</code>. The specialization
<code>hash&lt;typename UP::pointer&gt;</code> is required to be well-formed.
</ins></p>
</blockquote>

<pre><ins>template &lt;class T&gt; struct hash&lt;shared_ptr&lt;T&gt;&gt;;</ins></pre>

<blockquote>
<p><ins>
Specialization meeting the requirements of class template <code>hash</code> (22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a>). For an object <code>p</code> of type
<code>shared_ptr&lt;T&gt;</code>, <code>hash&lt;shared_ptr&lt;T&gt;&gt;()(p)</code>
shall evaluate to the same value as <code> hash&lt;T*&gt;()(p.get())</code>.
</ins></p>
</blockquote>
</blockquote>






</body>
</html>
