Section: 16.4.4.5 [hash.requirements] Status: C++11 Submitter: Daniel Krügler Opened: 2010-03-26 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [hash.requirements].
View all issues with C++11 status.
Discussion:
The currently added Hash
requirements demand in Table 40 — Hash
requirements [hash]:
Table 40 — Hash requirements [hash] Expression Return type Requirement h(k)
size_t
Shall not throw exceptions. [..]
While it surely is a generally accepted idea that hash function objects should not throw exceptions, this basic constraint for such a fundamental requirement set does neither match the current library policy nor real world cases:
The new definition goes beyond the original hash requirements as specified by SGI library in regard to the exception requirement:
noexcept
language facility libraries can still take
advantage of no-throw guarantees of hasher functions with stricter guarantees.
Even though the majority of all known move, swap, and hash functions won't throw and in some cases must not throw, it seems like unnecessary over-constraining the definition of a Hash functor not to propagate exceptions in any case and it contradicts the general principle of C++ to impose such a requirement for this kind of fundamental requirement.
[ 2010-11-11 Daniel asks the working group whether they would prefer a replacement for the second bullet of the proposed resolution (a result of discussing this with Alberto) of the form: ]
Add to 22.10.19 [unord.hash]/1 a new bullet:
1 The unordered associative containers defined in Clause 23.5 use specializations of the class template
hash
as the default hash function. For all object typesKey
for which there exists a specializationhash<Key>
, the instantiationhash<Key>
shall:
- satisfy the
Hash
requirements (20.2.4), withKey
as the function call argument type, theDefaultConstructible
requirements (33), theCopyAssignable
requirements (37),- be swappable (20.2.2) for lvalues,
- provide two nested types
result_type
andargument_type
which shall be synonyms forsize_t
andKey
, respectively,- satisfy the requirement that if
k1 == k2
is true,h(k1) == h(k2)
is also true, whereh
is an object of typehash<Key>
andk1
andk2
are objects of typeKey
,.- satisfy the requirement
noexcept(h(k)) == true
, whereh
is an object of typehash<Key>
andk
is an object of typeKey
, unlesshash<Key>
is a user-defined specialization that depends on at least one user-defined type.
[Batavia: Closed as NAD Future, then reopened. See the wiki for Tuesday.]
Proposed resolution:
Change Table 26 — Hash
requirements [tab:hash] as indicated:
Table 26 — Hash
requirements [tab:hash]Expression Return type Requirement h(k)
size_t
Shall not throw exceptions.[…]
Add to 22.10.19 [unord.hash] p. 1 a new bullet:
1 The unordered associative containers defined in Clause 23.5 [unord] use specializations of the class template
hash
as the default hash function. For all object typesKey
for which there exists a specializationhash<Key>
, the instantiationhash<Key>
shall:
- satisfy the
Hash
requirements ([hash.requirements]), withKey
as the function call argument type, theDefaultConstructible
requirements (Table [defaultconstructible]), theCopyAssignable
requirements (Table [copyassignable]),- be swappable ([swappable.requirements]) for lvalues,
- provide two nested types
result_type
andargument_type
which shall be synonyms forsize_t
andKey
, respectively,- satisfy the requirement that if
k1 == k2
is true,h(k1) == h(k2)
is also true, whereh
is an object of typehash<Key>
andk1
andk2
are objects of typeKey
,.- satisfy the requirement that the expression
h(k)
, whereh
is an object of typehash<Key>
andk
is an object of typeKey
, shall not throw an exception, unlesshash<Key>
is a user-defined specialization that depends on at least one user-defined type.