1182. Unfortunate hash dependencies

Section: 23.14.15 [unord.hash] Status: C++11 Submitter: Alisdair Meredith Opened: 2009-07-28 Last modified: 2016-02-10

Priority: Not Prioritized

View other active issues in [unord.hash].

View all other issues in [unord.hash].

View all issues with C++11 status.

Discussion:

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 23.14.15 [unord.hash].

[ 2009-09-15 Daniel adds: ]

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

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

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

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

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

Proposed resolution:

Strike the following specializations declared in the <functional> synopsis p2 23.14 [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 23.14.15 [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 23.14.15 [unord.hash].

Add the following declarations to 22.5 [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 23.14.15 [unord.hash].

Add the following declarations to the synopsis of <string> in 24.3 [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 23.14.15 [unord.hash].

Add the following declarations to the synopsis of <vector> in 26.3 [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 26.3.12 [vector.bool]

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

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

Add the following declarations to the synopsis of <bitset> in 23.9.2 [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 23.14.15 [unord.hash].

Add the following declarations to 33.3.2.1 [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 33.3.2.1 [thread.thread.id]:

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

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

Change Header <typeindex> synopsis 23.18.1 [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().