Pourquoi std :: hash est-il une structure plutôt qu’une fonction?

La bibliothèque standard implémente std :: hash en tant que structure de modèle spécialisée pour différents types. Il est utilisé comme ceci:

#include  #include  int main() { std::hash hasher; std::cout << hasher(1337) << std::endl; return 0; } 

Ma question est la suivante: quel est le raisonnement derrière ce choix de conception? Pourquoi n’est-il pas implémenté en tant que fonction modèle et utilisé comme ceci:

 #include  #include  int main() { std::cout << std::hash(1337) << std::endl; return 0; } 

Il existe de nombreuses raisons, chacune d’elles étant suffisante pour le choix:

  1. Vous pouvez partiellement spécialiser des modèles de classe, mais vous ne pouvez utiliser que des modèles de fonction entièrement spécialisés (du moins jusqu’à présent). Ainsi, vous pouvez fournir un remplacement pour toute une suite d’arguments de modèles associés, std::hash étant un modèle de classe. Notez que la surcharge partielle n’aide pas, car la fonction de hachage doit être spécifiée en tant qu’object, ce qui ne peut pas être fait avec des fonctions surchargées (à moins qu’elles ne soient accessibles via un object mais que c’est ce qui est différencié).
  2. Les conteneurs associatifs non ordonnés sont paramétrés avec une entité statique (qui peut également être personnalisée de manière dynamic si le type spécifique le permet), ce qui est plus facile à effectuer à l’aide de modèles de classe.
  3. Les entités utilisées pour la fonction de hachage étant personnalisables, vous pouvez choisir d’utiliser un type ou un pointeur de fonction pour la personnalisation. Les pointeurs de fonction sont souvent difficiles à intégrer, alors que les fonctions de membre en ligne d’un type sont sortingviales, améliorant ainsi les performances de fonctions simples telles que le calcul d’un simple hachage.

Une fonction de modèle ne peut pas être partiellement spécialisée pour les types, tandis que std::hash spécialisée pour différents types en tant que modèle de classe.

Et, de cette manière basée sur la classe de modèle, vous pouvez faire de la méta-programmation, comme accéder au type de retour et au type de clé comme ci-dessous:

 std::hash::argument_type std::hash::result_type