<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 2148: Hashing enums should be supported directly by std::hash</title>
<meta property="og:title" content="Issue 2148: Hashing enums should be supported directly by std::hash">
<meta property="og:description" content="C++ library issue. Status: C++14">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue2148.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++14">C++14</a> status.</em></p>
<h3 id="2148"><a href="lwg-defects.html#2148">2148</a>. Hashing enums should be supported directly by <code>std::hash</code></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++14">C++14</a>
 <b>Submitter:</b> Ville Voutilainen <b>Opened:</b> 2012-04-10 <b>Last modified:</b> 2016-08-03</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++14">C++14</a> status.</p>
<p><b>Discussion:</b></p>

<p>
The <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3333.html">paper</a> 
proposes various hashing improvements. What it doesn't mention is hashing of
enums; enums are integral types, and users expect them to have built-in hashing
support, rather than having to convert enums to ints for uses with
unordered containers and other uses of hashes. Daniel Kr&uuml;gler explains in c++std-lib-32412
that this is not achievable with a SFINAEd hash specialization because it would require
a partial specialization with a type parameter and a non-type parameter with a
default argument, which is currently not allowed, and hence the fixes in N3333 should be
adopted instead.
</p>

<p><i>[2012-10 Portland: Move to Open]</i></p>

<p>
We agree this is a real issue that should be resolved, by specifying such a hash.
</p>

<p>
It is not clear that we should specify this as calling hash on the <code>underlying_type</code>,
or whether that is overspecification and we merely require that the hash be supplied.
</p>

<p>
STL already has shipped an implementation, and is keen to provide wording.
</p>

<p><i>[
2013-04-14 STL provides rationale and improved wording
]</i></p>


<p>Rationale:</p>
<p>This can be achieved by inserting a very small tweak to the Standardese. We merely have to require that <code>hash&lt;Key&gt;</code> 
be valid when <code>Key</code> is an "enumeration type" (which includes both scoped and unscoped enums). This permits, but does 
not require, <code>hash&lt;Enum&gt;</code> to behave identically to <code>hash&lt;underlying_type&lt;Enum&gt;::type&gt;</code>, following 
existing precedent &mdash; note that when <code>unsigned int</code> and <code>unsigned long</code> are the same size, 
<code>hash&lt;unsigned int&gt;</code> is permitted-but-not-required to behave identically to <code>hash&lt;unsigned long&gt;</code>.
<p/>
This proposed resolution doesn't specify anything else about the primary template, allowing implementations to do 
whatever they want for non-enums: <code>static_assert</code> nicely, explode horribly at compiletime or runtime, etc.
<p/>
While we're in the neighborhood, this proposed resolution contains an editorial fix. The 22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>
synopsis says "base template", which doesn't appear anywhere else in the Standard, and could confuse users into 
thinking that they need to derive from it. The proper phrase is "primary template".
</p>

<p><i>[2013-04-18, Bristol]</i></p>




<p id="res-2148"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf">N3485</a>.</p>

<ol>
<li><p>In 22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>, header functional synopsis, edit as indicated:</p>

<blockquote><pre>
namespace std {
  [&hellip;]
  <i>// 20.8.12, hash function <del>base</del><ins>primary</ins> template:</i>
  template &lt;class T&gt; struct hash;
  [&hellip;]
}
</pre></blockquote>
</li>

<li><p>In 22.10.19 <a href="https://wg21.link/unord.hash">[unord.hash]</a>/1 edit as indicated:</p>

<blockquote><p>
-1- The unordered associative containers defined in 23.5 <a href="https://wg21.link/unord">[unord]</a> use specializations of the class template 
<code>hash</code> as the default <code>hash</code> function. For all object types <code>Key</code> for which there exists a 
specialization <code>hash&lt;Key&gt;</code><ins>, and for all enumeration types (9.8.1 <a href="https://wg21.link/dcl.enum">[dcl.enum]</a>) Key</ins>, 
the instantiation <code>hash&lt;Key&gt;</code> shall: [&hellip;]
</p></blockquote>
</li>
</ol>





</body>
</html>
