Title
Incorrect requirements for hash specializations
Status
c++14
Section
[syserr.hash][util.smartptr.hash][unord.hash] [type.index.synopsis][basic.string.hash][vector.bool] [thread.thread.id]
Submitter
Daniel Krügler

Created on 2011-12-04.00:00:00 last changed 123 months ago

Messages

Date: 2013-04-19.22:36:19

Proposed resolution:

  1. Change [syserr.hash] as indicated:

    template <> struct hash<error_code>;
    

    -1- Requires: tThe template specialization shall meet the requirements of class template hash ([unord.hash].

  2. Change [bitset.hash] as indicated:

    template <size_t N> struct hash<bitset<N> >;
    

    -1- Requires: tThe template specialization shall meet the requirements of class template hash ([unord.hash]).

  3. Change [util.smartptr.hash] as indicated:

    template <class T, class D> struct hash<unique_ptr<T, D> >;
    

    -1- Requires: tThe template specialization shall meet the requirements of class template hash ([unord.hash]). For an object p of type UP, where UP is unique_ptr<T, D>, hash<UP>()(p) shall evaluate to the same value as hash<typename UP::pointer>()(p.get()). The specialization hash<typename UP::pointer> shall be well-formed.

    -?- Requires: The specialization hash<typename UP::pointer> shall be well-formed and well-defined, and shall meet the requirements of class template hash ([unord.hash]).

    template <class T> struct hash<shared_ptr<T> >;
    

    -2- Requires: tThe template specialization shall meet the requirements of class template hash ([unord.hash]). For an object p of type shared_ptr<T>, hash<shared_ptr<T> >()(p) shall evaluate to the same value as hash<T*>()(p.get()).

  4. Change [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]

    template <> struct hash<bool>;
    template <> struct hash<char>;
    […]
    template <> struct hash<long double>;
    template <class T> struct hash<T*>;
    

    -2- Requires: tThe template specializations shall meet the requirements of class template hash ([unord.hash]).

  5. Change [type.index.hash] p1 as indicated:

    template <> struct hash<type_index>;
    

    -1- Requires: tThe template specialization shall meet the requirements of class template hash ([unord.hash]). For an object index of type type_index, hash<type_index>()(index) shall evaluate to the same result as index.hash_code().

  6. Change [basic.string.hash] p1 as indicated:

    template <> struct hash<string>;
    template <> struct hash<u16string>;
    template <> struct hash<u32string>;
    template <> struct hash<wstring>;
    

    -1- Requires: tThe template specializations shall meet the requirements of class template hash ([unord.hash]).

  7. Change [vector.bool] p7 as indicated:

    template <class Allocator> struct hash<vector<bool, Allocator> >;
    

    -7- Requires: tThe template specialization shall meet the requirements of class template hash ([unord.hash]).

  8. Change [thread.thread.id] p14 as indicated:

    template <> struct hash<thread::id>;
    

    -14- Requires: tThe template specialization shall meet the requirements of class template hash ([unord.hash]).

Date: 2013-04-20.00:00:00

[ 2013-04-20 Bristol ]

Date: 2012-10-20.00:32:14

[ 2012, Portland: Move to Tentatively Ready ]

No further wording issues, so move to Tentatively Ready (post meeting issues processing).

Date: 2012-02-27.16:24:02

[ Originally proposed wording for reference

  1. Change [syserr.hash] as indicated:

    template <> struct hash<error_code>;
    

    -1- Requires: the template specialization shall meet the requirements of class template hash ([unord.hash])The header <system_error> provides a definition for a specialization of the template hash<error_code>. The requirements for the members of this specialization are given in sub-clause [unord.hash].

  2. Change [bitset.hash] as indicated:

    template <size_t N> struct hash<bitset<N> >;
    

    -1- Requires: the template specialization shall meet the requirements of class template hash ([unord.hash])The header <bitset> provides a definition for a partial specialization of the hash class template for specializations of class template bitset<N>. The requirements for the members of instantiations of this specialization are given in sub-clause [unord.hash].

  3. Change [util.smartptr.hash] as indicated:

    template <class T, class D> struct hash<unique_ptr<T, D> >;
    

    -1- Requires: the template specialization shall meet the requirements of class template hash ([unord.hash])The header <memory> provides a definition for a partial specialization of the hash class template for specializations of class template unique_ptr<T, D>. The requirements for the members of instantiations of this specialization are given in sub-clause [unord.hash]. For an object p of type UP, where UP is unique_ptr<T, D>, hash<UP>()(p) shall evaluate to the same value as hash<typename UP::pointer>()(p.get()). The specialization hash<typename UP::pointer> shall be well-formed.

    -?- Requires: The specialization hash<typename UP::pointer> shall be well-formed and well-defined [Note: the general requirements of class template hash ([unord.hash]) are implied — end note].

    template <class T> struct hash<shared_ptr<T> >;
    

    -2- Requires: the template specialization shall meet the requirements of class template hash ([unord.hash])The header <memory> provides a definition for a partial specialization of the hash class template for specializations of class template shared_ptr<T>. The requirements for the members of instantiations of this specialization are given in sub-clause [unord.hash]. For an object p of type shared_ptr<T>, hash<shared_ptr<T> >()(p) shall evaluate to the same value as hash<T*>()(p.get()).

  4. Change [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]

    template <> struct hash<bool>;
    template <> struct hash<char>;
    […]
    template <> struct hash<long double>;
    template <class T> struct hash<T*>;
    

    -2- Requires: the template specializations shall meet the requirements of class template hash ([unord.hash])The header <functional> provides definitions for specializations of the hash class template for each cv-unqualified arithmetic type except for the extended integer types. This header also provides a definition for a partial specialization of the hash class template for any pointer type. The requirements for the members of these specializations are given in sub-clause [unord.hash].

  5. Change [type.index.hash] p1 as indicated:

    template <> struct hash<type_index>;
    

    -1- Requires: the template specialization shall meet the requirements of class template hash ([unord.hash])The header <typeindex> provides a definition for a specialization of the template hash<type_index>. The requirements for the members of this specialization are given in sub-clause [unord.hash]. For an object index of type type_index, hash<type_index>()(index) shall evaluate to the same result as index.hash_code().

  6. Change [basic.string.hash] p1 as indicated:

    template <> struct hash<string>;
    template <> struct hash<u16string>;
    template <> struct hash<u32string>;
    template <> struct hash<wstring>;
    

    -1- Requires: the template specializations shall meet the requirements of class template hash ([unord.hash])The header <string> provides definitions for specializations of the hash class template for the types string, u16string, u32string, and wstring. The requirements for the members of these specializations are given in sub-clause [unord.hash].

  7. Change [vector.bool] p7 as indicated:

    template <class Allocator> struct hash<vector<bool, Allocator> >;
    

    -7- Requires: the template specialization shall meet the requirements of class template hash ([unord.hash])The header <vector> provides a definition for a partial specialization of the hash class template for specializations of class template vector<bool, Allocator>. The requirements for the members of instantiations of this specialization are given in sub-clause [unord.hash].

  8. Change [thread.thread.id] p14 as indicated:

    template <> struct hash<thread::id>;
    

    -14- Requires: the template specialization shall meet the requirements of class template hash ([unord.hash])The header <thread> provides a definition for a specialization of the template hash<thread::id>. The requirements for the members of this specialization are given in sub-clause [unord.hash].

]

Date: 2012-02-27.16:24:02

[ 2012, Kona ]

Update wording and move to Review.

Believe a simpler formulation is to simply string the term Requires: and leave the current wording intact, rather than strike the whole clause and replace it.

Date: 2011-12-04.00:00:00

[util.smartptr.hash] p2 is specified as follows:

Requires: the template specializations shall meet the requirements of class template hash (20.8.12).

The problem here is the usage of a Requires element, which is actually a pre-condition that a user of a component has to satisfy. But the intent of this wording is actually to be a requirement on implementations. The Requires element should be removed here and the wording should be improved to say what it was intended for.

We have similar situations in basically all other places where the specification of library-provided hash specializations is defined. Usually, the Requires element is incorrect. In the special case of hash<unique_ptr<T, D>> the implementation depends on the behaviour of hash specializations, that could be user-provided. In this case the specification needs to separate the requirements on these specializations and those that are imposed on the implementation.

History
Date User Action Args
2014-02-20 13:20:35adminsetstatus: wp -> c++14
2013-04-25 19:07:07adminsetstatus: voting -> wp
2013-04-19 22:36:19adminsetmessages: + msg6479
2013-04-19 22:36:19adminsetstatus: ready -> voting
2012-10-20 00:32:14adminsetmessages: + msg6193
2012-10-20 00:32:14adminsetstatus: review -> ready
2012-02-27 16:24:02adminsetmessages: + msg6029
2012-02-27 16:24:02adminsetmessages: + msg6028
2012-02-12 18:36:43adminsetstatus: new -> review
2011-12-06 21:51:12adminsetmessages: + msg5954
2011-12-04 00:00:00admincreate