Comment se spécialisent std::hash<Key>::operator() pour le type défini par l'utilisateur non ordonnée dans les conteneurs?

À l'appui de l'utilisateur a défini les principaux types de std::unordered_set<Key> et std::unordered_map<Key, Value>
on doit fournir operator==(Key, Key) et un hachage foncteur:

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<int>()(x.id); }
};

std::unordered_set<X, MyHash> s;

Il serait plus commode d'écrire juste std::unordered_set<X>
avec un de hachage par défaut pour le type X,
comme pour les types à venir avec le compilateur et de la bibliothèque.
Après consultation de

il semble possible de se spécialiser std::hash<X>::operator():

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

Compte tenu de prise en charge du compilateur de C++11 est encore expérimental---je n'ai pas essayer Clang---, voici mes questions:

  1. Est-il légal d'ajouter une spécialisation à l'espace de noms std? J'ai des sentiments mitigés à ce sujet.

  2. Qui de la std::hash<X>::operator() versions, le cas échéant, est compatible avec le C++11?

  3. Est-il un portable moyen de le faire?

  • Avec gcc 4.7.2, j'ai dû fournir un mondial operator==(const Key, const Key)