Comment étendre std::tr1::hash pour les types personnalisés?
Comment puis-je permettre à la STL de mise en œuvre de ramasser mon type personnalisé? Sur MSVC, il existe une classe std::tr1::hash
, qui je peut partiellement se spécialisent en utilisant
namespace std
{
namespace tr1
{
template <>
struct hash<MyType>
{ ... };
}
}
mais est-ce recommandé? Par ailleurs, est-ce de travailler avec GCC de mise en œuvre ainsi? Pour boost::hash
, c'est suffisant pour fournir une fonction libre size_t hash_value (const MyType&)
, est-il quelque chose de similaire pour le TR1 mise en œuvre?
- Est-il un moyen d'étendre std::hash pour les types définis par l'utilisateur avec la copie privée, les constructeurs? Aussi, est-il possible de l'étendre avec un opérateur() qui prend un const ref au lieu de val?
- Quel est le problème avec le modèle de la spécialisation? Vous ne prenez pas une copie de votre objet (vous passez par les références), donc pas de problème -- et l'opérateur() prend un const ref ou de la valeur, tout ce que vous voulez. Regarder Phil Nash réponse, qui prend l'objet en tant que const réf.
Vous devez vous connecter pour publier un commentaire.
Oui, cela fonctionnera également pour GCC. Je l'utilise dans un projet plus vaste et il fonctionne sans problèmes. Vous pouvez également fournir votre propre personnalisé de hachage classe pour le TR1 conteneurs, mais il est précisé que std::tr1::hash<> est la valeur par défaut de hachage de la classe. Spécialisé pour les types personnalisés apparaît comme le moyen naturel d'étendre la norme de hachage de la fonctionnalité.
J'ai essayé de travailler la syntaxe exacte pour cela, avec le non-ordonnée des conteneurs associatifs (également à l'aide de GCC, comme l'OP demande) et appuyez sur cette question.
Malheureusement il n'est pas allé jusqu'au niveau de détail que je voulais. En regardant à travers la gcc en-têtes à la façon dont ils ont mis en œuvre la norme de fonctions de hachage je l'ai eu à travailler.
En vue de la rareté des exemples (au moins au moment de l'écriture) sur le web, j'ai pensé que ce serait le bon endroit pour poster mon propre exemple (ce que je peux confirmer fonctionne avec GCC):
(notez qu'il y a sont deux espaces de noms ici, c'est dans ma convention pour l'effondrement des espaces de noms imbriqués)
Que vous n'êtes pas ajouter à
std
de la bibliothèque de l'espace de noms, mais seulement en fournissant les spécialisations, alors il est parfaitement OK.Si vous souhaitez fournir plus générique de hachage approche (par exemple de hachage pour les tuples en général) puis un coup d'oeil à Stimuler la Fusion. Voici un exemple simple, qui fonctionnent pour la plupart des cas (probablement à l'exception de tuple de tuples)
L'extrait de code suivant montre comment se spécialisent
std::tr1::unordered_map
à la cartographieboost::const_string<char>
àvoid*
par analogie avec la façon dontstd::string
est haché.