Title
Unfortunate hash dependencies
Status
c++11
Section
[unord.hash]
Submitter
Alisdair Meredith

Created on 2009-07-28.00:00:00 last changed 153 months ago

Messages

Date: 2010-10-21.18:28:33

Proposed resolution:

Strike the following specializations declared in the <functional> synopsis p2 [function.objects]

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

template <> struct hash<std::error_code>;
template <> struct hash<std::thread::id>;
template <class Allocator> struct hash<std::vector<bool, Allocator> >;
template <std::size_t N> struct hash<std::bitset<N> >;

Add the following at the end of [unord.hash]:

template <> struct hash<bool>;
template <> struct hash<char>;
template <> struct hash<signed char>;
template <> struct hash<unsigned char>;
template <> struct hash<char16_t>;
template <> struct hash<char32_t>;
template <> struct hash<wchar_t>;
template <> struct hash<short>;
template <> struct hash<unsigned short>;
template <> struct hash<int>;
template <> struct hash<unsigned int>;
template <> struct hash<long>;
template <> struct hash<long long>;
template <> struct hash<unsigned long>;
template <> struct hash<unsigned long long>;
template <> struct hash<float>;
template <> struct hash<double>;
template <> struct hash<long double>;
template<class T> struct hash<T*>;

Specializations meeting the requirements of class template hash [unord.hash].

Add the following declarations to [syserr], header <system_error> synopsis after // 19.5.4:

// [syserr.hash] hash support
template <class T> struct hash;
template <> struct hash<error_code>;

Add a new clause 19.5.X (probably after 19.5.4):

19.5.X Hash support [syserr.hash]

template <> struct hash<error_code>;

Specialization meeting the requirements of class template hash [unord.hash].

Add the following declarations to the synopsis of <string> in [string.classes]

// [basic.string.hash] hash support
template <class T> struct hash;
template <> struct hash<string>;
template <> struct hash<u16string>;
template <> struct hash<u32string>;
template <> struct hash<wstring>;

Add a new clause 21.4.X

21.4.X Hash support [basic.string.hash]>

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

Specializations meeting the requirements of class template hash [unord.hash].

Add the following declarations to the synopsis of <vector> in [sequences]

// 21.4.x hash support
template <class T> struct hash;
template <class Allocator> struct hash<vector<bool, Allocator>>;

Add a new paragraph to the end of [vector.bool]

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

Specialization meeting the requirements of class template hash [unord.hash].

Add the following declarations to the synopsis of <bitset> in [template.bitset]

// [bitset.hash] hash support
template <class T> struct hash;
template <size_t N> struct hash<bitset<N> >;

Add a new subclause 20.3.7.X [bitset.hash]

20.3.7.X bitset hash support [bitset.hash]

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

Specialization meeting the requirements of class template hash [unord.hash].

Add the following declarations to [thread.thread.id] synopsis just after the declaration of the comparison operators:

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

Add a new paragraph at the end of [thread.thread.id]:

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

Specialization meeting the requirements of class template hash [unord.hash].

Change Header <typeindex> synopsis [type.index.synopsis] as indicated:

namespace std {
class type_index;
  // [type.index.hash] hash support
  template <class T> struct hash;
  template<> struct hash<type_index>;  : public unary_function<type_index, size_t> {
    size_t operator()(type_index index) const;
  }
}

Change Template specialization hash<type_index> [type.index.templ] as indicated:

20.11.4 Template specialization hash<type_index> [type.index.templ] Hash support [type.index.hash]

size_t operator()(type_index index) const;

Returns: index.hash_code()

template<> struct hash<type_index>;

Specialization meeting 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 value as index.hash_code().

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 wording updated by Beman, Daniel, Alisdair and Ganesh. ]

Date: 2010-01-31.00:00:00

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

Date: 2009-11-13.00:00:00

[ 2009-11-13 Alisdair adopts Daniel's suggestion and the extended note from 889. ]

Date: 2009-09-15.00:00:00

[ 2009-09-15 Daniel adds: ]

I suggest to add to the current existing proposed resolution the following items.

  • Add to the very first strike-list of the currently suggested resolution the following lines:

    template <> struct hash<std::error_code>;
    template <> struct hash<std::thread::id>;
    
  • Add the following declarations to [syserr], header <system_error> synopsis after // 19.5.4:

    
    // 19.5.x hash support
    template <class T> struct hash;
    template <> struct hash<error_code>;
    
    
  • Add a new clause 19.5.X (probably after 19.5.4):

    19.5.X Hash support [syserr.hash]

    
    template <> struct hash<error_code>;
    

    An explicit specialization of the class template hash ([unord.hash]) shall be provided for the type error_code suitable for using this type as key in unordered associative containers ([unord]).

  • Add the following declarations to [thread.thread.id] just after the declaration of the comparison operators:

    
    template <class T> struct hash;
    template <> struct hash<thread::id>;
    
  • Add a new paragraph at the end of [thread.thread.id]:

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

    An explicit specialization of the class template hash ([unord.hash]) shall be provided for the type thread::id suitable for using this type as key in unordered associative containers ([unord]).

  • Issue 889 independently suggests moving the specialization std::hash<std::thread::id> to header <thread>.
Date: 2009-07-28.00:00:00

Addresses UK 324

The implied library dependencies created by spelling out all the hash template specializations in the <functional> synopsis are unfortunate. The potential coupling is greatly reduced if the hash specialization is declared in the appropriate header for each library type, as it is much simpler to forward declare the primary template and provide a single specialization than it is to implement a hash function for a string or vector without providing a definition for the whole string/vector template in order to access the necessary bits.

Note that the proposed resolution purely involves moving the declarations of a few specializations, it specifically does not make any changes to [unord.hash].

History
Date User Action Args
2011-08-23 20:07:26adminsetstatus: wp -> c++11
2010-10-21 18:28:33adminsetmessages: + msg1049
2010-10-21 18:28:33adminsetmessages: + msg1048
2010-10-21 18:28:33adminsetmessages: + msg1047
2010-10-21 18:28:33adminsetmessages: + msg1046
2010-10-21 18:28:33adminsetmessages: + msg1045
2010-10-21 18:28:33adminsetmessages: + msg1044
2009-07-28 00:00:00admincreate