<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1245: std::hash&lt;string&gt; &amp; co</title>
<meta property="og:title" content="Issue 1245: std::hash&lt;string&gt; &amp; co">
<meta property="og:description" content="C++ library issue. Status: C++11">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1245.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="1245"><a href="lwg-defects.html#1245">1245</a>. <code>std::hash&lt;string&gt;</code> &amp; co</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> Paolo Carlini <b>Opened:</b> 2009-10-22 <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>
In 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a>, <code>operator()</code> is specified as
taking the argument by value. Moreover, it is said that <code>operator()</code> shall
not throw exceptions.
</p>

<p>
However, for the specializations for class types, like <code>string</code>, 
<code>wstring</code>, etc, the former requirement seems suboptimal from the 
performance point of view (a specific PR has been filed about this in the GCC Bugzilla)
and, together with the latter requirement, hard if not impossible to
fulfill. It looks like pass by const reference should be allowed in such
cases.
</p>

<p><i>[
2009-11-18: Ganesh updates wording.
]</i></p>


<blockquote><p>
I've removed the list of types for which <code>hash</code> shall be instantiated
because it's already explicit in the synopsis of header
<code>&lt;functional&gt;</code> in 22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>/2.
</p></blockquote>

<p><i>[
2009-11-18: Original wording here:
]</i></p>


<blockquote class="note">
<p>
Add to 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a>/2:
</p>

<blockquote>
<pre>
namespace std {
  template &lt;class T&gt;
  struct hash : public std::unary_function&lt;T, std::size_t&gt; {
    std::size_t operator()(T val) const;
  };
}
</pre>

<p>
The return value of <code>operator()</code> is unspecified, except that
equal arguments shall yield the same result. <code>operator()</code> shall
not throw exceptions. <ins>It is also unspecified whether
<code>operator()</code> of <code>std::hash</code> specializations for class
types takes its argument by value or const reference.</ins>
</p>
</blockquote>
</blockquote>

<p><i>[
2009-11-19 Moved to Tentatively Ready after 5 positive votes on c++std-lib.
]</i></p>


<p><i>[
2009-11-24 Ville Opens:
]</i></p>


<blockquote><p>
I have received community requests to ask for this issue to be reopened.
Some users feel that mandating the inheritance is overly constraining.
</p></blockquote>

<p><i>[
2010-01-31 Alisdair: related to <a href="lwg-defects.html#978" title="Hashing smart pointers (Status: C++11)">978</a><sup><a href="https://cplusplus.github.io/LWG/issue978" 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-07 Proposed resolution updated by Beman, Daniel and Ganesh.
]</i></p>


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




<p id="res-1245"><b>Proposed resolution:</b></p>
  <p><i>Insert a new subclause either before or after the current 16.4.4.6 <a href="https://wg21.link/allocator.requirements">[allocator.requirements]</a>:</i></p>
<blockquote>

  <h3><code>Hash</code> Requirements [hash.requirements]</h3>

  <p>This subclause defines the named requirement <code>Hash</code>, 
  used in several clauses of the C++ standard library. A type <code>H</code> meets the <code>Hash</code> requirement if</p>

  <ul>
    <li>

  <p>it is a function object type (22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>).</p>

    </li>
    <li>

  <p>it satisfies the requirements of <code>CopyConstructible</code>, and 
  <code>Destructible</code> (16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a>),</p>

    </li>
    <li>

  <p>the expressions shown in the following table are valid and have the 
  indicated semantics, and</p>

    </li>
    <li>

  <p>it satisfies all other requirements of this subclause.</p>

    </li>
  </ul>

  <p>Given <code>Key</code> is an argument type for function objects of 
  type <code>H</code>, in the table below <code>h</code> is a value of type (possibly <code>const</code>)
  <code>H</code>, <code>u</code> is an lvalue of type <code>Key</code>,&nbsp; and <code>
  k</code> 
  is a value of a type convertible to (possibly <code>const</code>) <code>Key</code>:</p>

<table border="1" cellpadding="5" cellspacing="1" style="border-collapse: collapse">
  <caption>Table ? &mdash; <code>Hash</code> requirements</caption>
  <tr>
    <td>Expression</td>
    <td>Return type</td>
    <td>Requirement</td>
  </tr>
  <tr>
    <td valign="top"><code>h(k)</code></td>
    <td valign="top"><code>size_t</code></td>
    <td valign="top">Shall not throw exceptions. The value returned shall depend only on
the argument <code>k</code>. [<i>Note:</i> Thus all evaluations of the expression <code>
    h(k)</code> with the 
    same value for <code>k</code> yield the same result. <i>&mdash; end note</i>] [<i>Note:
    </i>For <code>t1</code> and <code>t2</code> of different values, the probability that 
    <code>h(t1)</code> 
    and <code>h(t2)</code> compare equal should be very small, approaching <code>(1.0/numeric_limits&lt;size_t&gt;::max())</code>.
    <i>&mdash; end note</i>] <i><span style="color:#C0C0C0">Comment 
    (not to go in WP): The wording for the second note is based on a similar 
    note in 28.3.4.5.1.3 <a href="https://wg21.link/locale.collate.virtuals">[locale.collate.virtuals]</a>/3</span></i></td>
  </tr>
  <tr>
    <td valign="top"><code>h(u)</code></td>
    <td valign="top"><code>size_t</code></td>
    <td valign="top">Shall not modify <code>u</code>.</td>
  </tr>
  </table>

</blockquote>

<p><i>Change 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a> as indicated: </i>
</p>
<blockquote>
  <p>1 The unordered associative containers defined in Clause 23.5 <a href="https://wg21.link/unord">[unord]</a> use 
  specializations of <ins>the class template</ins> <code>hash</code> as the default 
  hash function. <ins>For all object types <code>T</code> for which there exists a 
  specialization <code>hash&lt;T&gt;</code>, the instantiation <code>hash&lt;T&gt;</code> shall:</ins></p>
  <ul>
    <li> <ins>satisfy the <code>Hash</code> requirements([hash.requirements]), with <code>T</code> as the 
  function call argument type, the <code>
  DefaultConstructible</code> requirements ([defaultconstructible]), the <code>CopyAssignable</code> 
  requirements ([copyassignable]), and the <code>
  Swappable</code> requirements ([swappable]),</ins>
  </li>
    <li> <ins>provide two nested types <code>result_type</code> and <code>argument_type</code> which shall 
    be synonyms for <code>size_t</code> and <code>T</code>, respectively,</ins></li>
    <li> <ins>satisfy the 
  requirement that if <code>k1 == k2</code> is <code>true</code>, <code>h(k1) == h(k2)</code> 
  is <code>true</code>, where <code>h</code> is an object of type <code>hash&lt;T&gt;</code>, and
  <code>k1</code>, <code>k2</code> are objects of type <code>T</code>.</ins></li>
  </ul>
  <p> <del>This class template is only required to be instantiable 
  for integer types (6.9.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a>), floating-point types (6.9.2 <a href="https://wg21.link/basic.fundamental">[basic.fundamental]</a>), 
  pointer types (9.3.4.2 <a href="https://wg21.link/dcl.ptr">[dcl.ptr]</a>), and <code>std::string</code>, <code>std::u16string</code>,
  <code>std::u32string</code>, <code>std::wstring</code>, <code>std::error_code</code>, <code>
  std::thread::id</code>, <code>std::bitset</code>, and <code>std::vector&lt;bool&gt;</code>.</del> </p>
  <blockquote>
    <pre><del>namespace std {
  template &lt;class T&gt;
  struct hash : public std::unary_function&lt;T, std::size_t&gt; {
    std::size_t operator()(T val) const;
  };
}</del></pre>
  </blockquote>
  <p><del>2 The return value of <code>operator()</code> is unspecified, except that 
  equal arguments shall yield the same result. <code>operator()</code> shall not 
  throw exceptions. </del></p>

</blockquote>

  <p><i>Change Unordered associative containers 23.2.8 <a href="https://wg21.link/unord.req">[unord.req]</a> as indicated:</i></p>
<blockquote>
  <p>Each unordered associative container is parameterized by <code>Key</code>, by a 
  function object <ins>type</ins> <code>Hash</code><ins>([hash.requirements])</ins> that acts as a hash 
  function for <ins>argument</ins> values of type <code>Key</code>, 
  and by a binary predicate <code>Pred</code> that induces an equivalence relation 
  on values of type <code>Key</code>. Additionally, <code>unordered_map</code> and <code>
  unordered_multimap</code> associate an arbitrary mapped type <code>T</code> with the
  <code>Key</code>.</p>
  <p>A hash function is a function object that takes a single argument of type
  <code>Key</code> and returns a value of type <code>std::size_t</code>.</p>
<p>Two values <code>k1</code> and <code>k2</code> of type <code>Key</code> are considered 
equal if the container's equality function object returns <code>true</code> when passed those 
values. If <code>k1</code> and <code>k2</code> are equal, the hash function shall return 
the same value for both. <ins>[<i>Note:</i> Thus supplying a non-default <code>Pred</code> 
parameter usually implies the need to supply a non-default <code>Hash</code> 
parameter. <i>&mdash; end note</i>]</ins></p>

</blockquote>






</body>
</html>
