Как специализировать std :: hash :: operator () для определяемого пользователем типа в неупорядоченных контейнерах?

Для поддержки определяемых пользователем типов ключей в std :: unordered_set и std :: unordered_map необходимо предоставить operator == (Key, Key) и хеш-функтор:

struct X { int id; /* ... */ };
bool operator==(X a, X b) { return a.id == b.id; }

struct MyHash {
  size_t operator()(const X& x) const { return std::hash()(x.id); }
};

std::unordered_set s;

Было бы удобнее написать только std :: unordered_set с хешем по умолчанию для типа X , как для типов, поставляемых вместе с компилятором и библиотекой. После ознакомления с

кажется возможным специализироваться std :: hash :: operator () :

namespace std { // argh!
  template <>
  inline size_t 
  hash::operator()(const X& x) const { return hash()(x.id); } // works for MS VC10, but not for g++
  // or
  // hash::operator()(X x) const { return hash()(x.id); }     // works for g++ 4.7, but not for VC10 
}                                                                             

Учитывая, что компилятор поддерживает C ++ 11 пока что экспериментальный --- я не пробовал Clang ---, вот мои вопросы:

  1. Законно ли добавлять такую ​​специализацию? цию в пространство имен std ? У меня смешанные чувства по этому поводу.

  2. Какая из версий std :: hash :: operator () , если таковая имеется, совместима со стандартом C ++ 11?

  3. Есть ли переносимый способ сделать это?

95
задан Community 23 May 2017 в 12:18
поделиться