std::hash<string>
& coSection: 22.10.19 [unord.hash] Status: C++11 Submitter: Paolo Carlini Opened: 2009-10-22 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [unord.hash].
View all issues with C++11 status.
Discussion:
In 22.10.19 [unord.hash], operator()
is specified as
taking the argument by value. Moreover, it is said that operator()
shall
not throw exceptions.
However, for the specializations for class types, like string
,
wstring
, 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.
[ 2009-11-18: Ganesh updates wording. ]
I've removed the list of types for which
hash
shall be instantiated because it's already explicit in the synopsis of header<functional>
in 22.10 [function.objects]/2.
[ 2009-11-18: Original wording here: ]
Add to 22.10.19 [unord.hash]/2:
namespace std { template <class T> struct hash : public std::unary_function<T, std::size_t> { std::size_t operator()(T val) const; }; }The return value of
operator()
is unspecified, except that equal arguments shall yield the same result.operator()
shall not throw exceptions. It is also unspecified whetheroperator()
ofstd::hash
specializations for class types takes its argument by value or const reference.
[ 2009-11-19 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]
[ 2009-11-24 Ville Opens: ]
I have received community requests to ask for this issue to be reopened. Some users feel that mandating the inheritance is overly constraining.
[ 2010-01-31 Alisdair: related to 978 and 1182. ]
[ 2010-02-07 Proposed resolution updated by Beman, Daniel and Ganesh. ]
[ 2010-02-09 Moved to Tentatively Ready after 5 positive votes on c++std-lib. ]
Proposed resolution:
Insert a new subclause either before or after the current 16.4.4.6 [allocator.requirements]:
Hash
Requirements [hash.requirements]This subclause defines the named requirement
Hash
, used in several clauses of the C++ standard library. A typeH
meets theHash
requirement if
it is a function object type (22.10 [function.objects]).
it satisfies the requirements of
CopyConstructible
, andDestructible
(16.4.4.2 [utility.arg.requirements]),the expressions shown in the following table are valid and have the indicated semantics, and
it satisfies all other requirements of this subclause.
Given
Key
is an argument type for function objects of typeH
, in the table belowh
is a value of type (possiblyconst
)H
,u
is an lvalue of typeKey
, andk
is a value of a type convertible to (possiblyconst
)Key
:
Table ? — Hash
requirementsExpression Return type Requirement h(k)
size_t
Shall not throw exceptions. The value returned shall depend only on the argument k
. [Note: Thus all evaluations of the expressionh(k)
with the same value fork
yield the same result. — end note] [Note: Fort1
andt2
of different values, the probability thath(t1)
andh(t2)
compare equal should be very small, approaching(1.0/numeric_limits<size_t>::max())
. — end note] 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 [locale.collate.virtuals]/3h(u)
size_t
Shall not modify u
.
Change 22.10.19 [unord.hash] as indicated:
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 typesT
for which there exists a specializationhash<T>
, the instantiationhash<T>
shall:
- satisfy the
Hash
requirements([hash.requirements]), withT
as the function call argument type, theDefaultConstructible
requirements ([defaultconstructible]), theCopyAssignable
requirements ([copyassignable]), and theSwappable
requirements ([swappable]),- provide two nested types
result_type
andargument_type
which shall be synonyms forsize_t
andT
, respectively,- satisfy the requirement that if
k1 == k2
istrue
,h(k1) == h(k2)
istrue
, whereh
is an object of typehash<T>
, andk1
,k2
are objects of typeT
.
This class template is only required to be instantiable for integer types (6.8.2 [basic.fundamental]), floating-point types (6.8.2 [basic.fundamental]), pointer types (9.3.4.2 [dcl.ptr]), andstd::string
,std::u16string
,std::u32string
,std::wstring
,std::error_code
,std::thread::id
,std::bitset
, andstd::vector<bool>
.namespace std { template <class T> struct hash : public std::unary_function<T, std::size_t> { std::size_t operator()(T val) const; }; }
2 The return value ofoperator()
is unspecified, except that equal arguments shall yield the same result.operator()
shall not throw exceptions.
Change Unordered associative containers 23.2.8 [unord.req] as indicated:
Each unordered associative container is parameterized by
Key
, by a function object typeHash
([hash.requirements]) that acts as a hash function for argument values of typeKey
, and by a binary predicatePred
that induces an equivalence relation on values of typeKey
. Additionally,unordered_map
andunordered_multimap
associate an arbitrary mapped typeT
with theKey
.A hash function is a function object that takes a single argument of type
Key
and returns a value of typestd::size_t
.Two values
k1
andk2
of typeKey
are considered equal if the container's equality function object returnstrue
when passed those values. Ifk1
andk2
are equal, the hash function shall return the same value for both. [Note: Thus supplying a non-defaultPred
parameter usually implies the need to supply a non-defaultHash
parameter. — end note]