std::hash
Section: 22.10.19 [unord.hash] Status: C++14 Submitter: Ville Voutilainen Opened: 2012-04-10 Last modified: 2016-08-03
Priority: Not Prioritized
View all other issues in [unord.hash].
View all issues with C++14 status.
Discussion:
The paper 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ü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.
[2012-10 Portland: Move to Open]
We agree this is a real issue that should be resolved, by specifying such a hash.
It is not clear that we should specify this as calling hash on the underlying_type
,
or whether that is overspecification and we merely require that the hash be supplied.
STL already has shipped an implementation, and is keen to provide wording.
[ 2013-04-14 STL provides rationale and improved wording ]
Rationale:
This can be achieved by inserting a very small tweak to the Standardese. We merely have to require that hash<Key>
be valid when Key
is an "enumeration type" (which includes both scoped and unscoped enums). This permits, but does
not require, hash<Enum>
to behave identically to hash<underlying_type<Enum>::type>
, following
existing precedent — note that when unsigned int
and unsigned long
are the same size,
hash<unsigned int>
is permitted-but-not-required to behave identically to hash<unsigned long>
.
static_assert
nicely, explode horribly at compiletime or runtime, etc.
While we're in the neighborhood, this proposed resolution contains an editorial fix. The 22.10 [function.objects]
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".
[2013-04-18, Bristol]
Proposed resolution:
This wording is relative to N3485.
In 22.10 [function.objects], header functional synopsis, edit as indicated:
namespace std { […] // 20.8.12, hash functionbaseprimary template: template <class T> struct hash; […] }
In 22.10.19 [unord.hash]/1 edit as indicated:
-1- The unordered associative containers defined in 23.5 [unord] use specializations of the class template
hash
as the defaulthash
function. For all object typesKey
for which there exists a specializationhash<Key>
, and for all enumeration types (9.7.1 [dcl.enum]) Key, the instantiationhash<Key>
shall: […]