This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++14 status.
hash
specializationsSection: 19.5.7 [syserr.hash], 20.3.3 [util.smartptr.hash], 22.10.19 [unord.hash], 17.7.6 [type.index.synopsis], 27.4.6 [basic.string.hash], 23.3.12 [vector.bool], 32.4.3.2 [thread.thread.id] Status: C++14 Submitter: Daniel Krügler Opened: 2011-12-04 Last modified: 2016-01-28
Priority: Not Prioritized
View all issues with C++14 status.
Discussion:
20.3.3 [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-providedhash
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.
[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.
[Originally proposed wording for reference
Change 19.5.7 [syserr.hash] as indicated:
-1- Change 22.9.3 [bitset.hash] as indicated:
-1- Change 20.3.3 [util.smartptr.hash] as indicated:
-1-
template <> struct hash<error_code>;
Requires: the template specialization shall meet the requirements
of class template The header
hash
(22.10.19 [unord.hash])<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 22.10.19 [unord.hash].
template <size_t N> struct hash<bitset<N> >;
Requires: the template specialization shall meet the requirements
of class template The header
hash
(22.10.19 [unord.hash])<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 22.10.19 [unord.hash].
template <class T, class D> struct hash<unique_ptr<T, D> >;
Requires: the template specialization shall meet the requirements
of class template The header
hash
(22.10.19 [unord.hash])<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 22.10.19 [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.hash<typename UP::pointer>
shall be well-formed and well-defined [Note: the general requirements
of class template hash
(22.10.19 [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 templateThe headerhash
(22.10.19 [unord.hash])<memory>
provides a definition for a partial specialization of thehash
class template for specializations of class templateshared_ptr<T>
. The requirements for the members of instantiations of this specialization are given in sub-clause 22.10.19 [unord.hash]. For an objectp
of typeshared_ptr<T>
,hash<shared_ptr<T> >()(p)
shall evaluate to the same value ashash<T*>()(p.get())
.
Change 22.10.19 [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(i) 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 templateThe headerhash
(22.10.19 [unord.hash])<functional>
provides definitions for specializations of thehash
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 thehash
class template for any pointer type. The requirements for the members of these specializations are given in sub-clause 22.10.19 [unord.hash].
Change [type.index.hash] p1 as indicated:
template <> struct hash<type_index>;-1-
Requires: the template specialization shall meet the requirements of class templateThe headerhash
(22.10.19 [unord.hash])<typeindex>
provides a definition for a specialization of the templatehash<type_index>
. The requirements for the members of this specialization are given in sub-clause 22.10.19 [unord.hash]. For an objectindex
of typetype_index
,hash<type_index>()(index)
shall evaluate to the same result asindex.hash_code()
.
Change 27.4.6 [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 templateThe headerhash
(22.10.19 [unord.hash])<string>
provides definitions for specializations of thehash
class template for the typesstring
,u16string
,u32string
, andwstring
. The requirements for the members of these specializations are given in sub-clause 22.10.19 [unord.hash].
Change 23.3.12 [vector.bool] p7 as indicated:
template <class Allocator> struct hash<vector<bool, Allocator> >;-7-
Requires: the template specialization shall meet the requirements of class templateThe headerhash
(22.10.19 [unord.hash])<vector>
provides a definition for a partial specialization of thehash
class template for specializations of class templatevector<bool, Allocator>
. The requirements for the members of instantiations of this specialization are given in sub-clause 22.10.19 [unord.hash].
Change 32.4.3.2 [thread.thread.id] p14 as indicated:
template <> struct hash<thread::id>;-14-
Requires: the template specialization shall meet the requirements of class templateThe headerhash
(22.10.19 [unord.hash])<thread>
provides a definition for a specialization of the templatehash<thread::id>
. The requirements for the members of this specialization are given in sub-clause 22.10.19 [unord.hash].
[2012, Portland: Move to Tentatively Ready]
No further wording issues, so move to Tentatively Ready (post meeting issues processing).
[2013-04-20 Bristol]
Proposed resolution:
Change 19.5.7 [syserr.hash] as indicated:
template <> struct hash<error_code>;-1-
Requires: tThe template specialization shall meet the requirements of class templatehash
(22.10.19 [unord.hash].
Change 22.9.3 [bitset.hash] as indicated:
template <size_t N> struct hash<bitset<N> >;-1-
Requires: tThe template specialization shall meet the requirements of class templatehash
(22.10.19 [unord.hash]).
Change 20.3.3 [util.smartptr.hash] as indicated:
template <class T, class D> struct hash<unique_ptr<T, D> >;-1-
-?- Requires: The specializationRequires: tThe template specialization shall meet the requirements of class templatehash
(22.10.19 [unord.hash]). For an objectp
of typeUP
, whereUP
isunique_ptr<T, D>
,hash<UP>()(p)
shall evaluate to the same value ashash<typename UP::pointer>()(p.get())
.The specializationhash<typename UP::pointer>
shall be well-formed.hash<typename UP::pointer>
shall be well-formed and well-defined, and shall meet the requirements of class templatehash
(22.10.19 [unord.hash]).
template <class T> struct hash<shared_ptr<T> >;-2-
Requires: tThe template specialization shall meet the requirements of class templatehash
(22.10.19 [unord.hash]). For an objectp
of typeshared_ptr<T>
,hash<shared_ptr<T> >()(p)
shall evaluate to the same value ashash<T*>()(p.get())
.
Change 22.10.19 [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(i) 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 templatehash
(22.10.19 [unord.hash]).
Change [type.index.hash] p1 as indicated:
template <> struct hash<type_index>;-1-
Requires: tThe template specialization shall meet the requirements of class templatehash
(22.10.19 [unord.hash]). For an objectindex
of typetype_index
,hash<type_index>()(index)
shall evaluate to the same result asindex.hash_code()
.
Change 27.4.6 [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 templatehash
(22.10.19 [unord.hash]).
Change 23.3.12 [vector.bool] p7 as indicated:
template <class Allocator> struct hash<vector<bool, Allocator> >;-7-
Requires: tThe template specialization shall meet the requirements of class templatehash
(22.10.19 [unord.hash]).
Change 32.4.3.2 [thread.thread.id] p14 as indicated:
template <> struct hash<thread::id>;-14-
Requires: tThe template specialization shall meet the requirements of class templatehash
(22.10.19 [unord.hash]).