Title
std::hash<string> & co
Status
c++11
Section
[unord.hash]
Submitter
Paolo Carlini

Created on 2009-10-22.00:00:00 last changed 161 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Insert a new subclause either before or after the current [allocator.requirements]:

Hash Requirements [hash.requirements]

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

  • it is a function object type ([function.objects]).

  • it satisfies the requirements of CopyConstructible, and Destructible ([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 type H, in the table below h is a value of type (possibly const) H, u is an lvalue of type Key,  and k is a value of a type convertible to (possibly const) Key:

Table ? — Hash requirements
Expression 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 expression h(k) with the same value for k yield the same result. — end note] [Note: For t1 and t2 of different values, the probability that h(t1) and h(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 [locale.collate.virtuals]/3
h(u) size_t Shall not modify u.

Change [unord.hash] as indicated:

1 The unordered associative containers defined in Clause [unord] use specializations of the class template hash as the default hash function. For all object types T for which there exists a specialization hash<T>, the instantiation hash<T> shall:

  • satisfy the Hash requirements([hash.requirements]), with T as the function call argument type, the DefaultConstructible requirements ([defaultconstructible]), the CopyAssignable requirements ([copyassignable]), and the Swappable requirements ([swappable]),
  • provide two nested types result_type and argument_type which shall be synonyms for size_t and T, respectively,
  • satisfy the requirement that if k1 == k2 is true, h(k1) == h(k2) is true, where h is an object of type hash<T>, and k1, k2 are objects of type T.

This class template is only required to be instantiable for integer types ([basic.fundamental]), floating-point types ([basic.fundamental]), pointer types ([dcl.ptr]), and std::string, std::u16string, std::u32string, std::wstring, std::error_code, std::thread::id, std::bitset, and std::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 of operator() is unspecified, except that equal arguments shall yield the same result. operator() shall not throw exceptions.

Change Unordered associative containers [unord.req] as indicated:

Each unordered associative container is parameterized by Key, by a function object type Hash([hash.requirements]) that acts as a hash function for argument values of type Key, and by a binary predicate Pred that induces an equivalence relation on values of type Key. Additionally, unordered_map and unordered_multimap associate an arbitrary mapped type T with the Key.

A hash function is a function object that takes a single argument of type Key and returns a value of type std::size_t.

Two values k1 and k2 of type Key are considered equal if the container's equality function object returns true when passed those values. If k1 and k2 are equal, the hash function shall return the same value for both. [Note: Thus supplying a non-default Pred parameter usually implies the need to supply a non-default Hash parameter. — end note]

Date: 2010-02-09.00:00:00

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

Date: 2010-02-07.00:00:00

[ 2010-02-07 Proposed resolution updated by Beman, Daniel and Ganesh. ]

Date: 2010-01-31.00:00:00

[ 2010-01-31 Alisdair: related to 978 and 1182. ]

Date: 2009-11-24.00:00:00

[ 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.

Date: 2009-11-19.00:00:00

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

Date: 2009-11-18.00:00:00

[ 2009-11-18: Original wording here: ]

Add to [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 whether operator() of std::hash specializations for class types takes its argument by value or const reference.

Date: 2009-11-18.00:00:00

[ 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 [function.objects]/2.

Date: 2009-10-22.00:00:00

In [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.

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2010-10-21 18:28:33adminsetmessages: + msg1295
2010-10-21 18:28:33adminsetmessages: + msg1294
2010-10-21 18:28:33adminsetmessages: + msg1293
2010-10-21 18:28:33adminsetmessages: + msg1292
2010-10-21 18:28:33adminsetmessages: + msg1291
2010-10-21 18:28:33adminsetmessages: + msg1290
2010-10-21 18:28:33adminsetmessages: + msg1289
2010-10-21 18:28:33adminsetmessages: + msg1288
2009-10-22 00:00:00admincreate