Почему std :: hash структура вместо функции?

Стандартная библиотека реализует std :: hash как шаблонную структуру, которая специализируется для разных типов. Используется так:

#include <iostream>
#include <functional>

int main()
{
std::hash<int> hasher;
std::cout << hasher(1337) << std::endl;

return 0;
}

Мой вопрос заключается в том, что является причиной этого выбора дизайна. Почему это не реализовано как шаблонная функция и не используется так:

#include <iostream>
#include <functional>

int main()
{
std::cout << std::hash<int>(1337) << std::endl;

return 0;
}

17

Решение

Есть несколько причин, каждая из которых достаточно хороша для выбора:

  1. Вы можете частично специализировать шаблоны классов, но вы можете только полностью специализированные шаблоны функций (по крайней мере, пока). Таким образом, вы можете обеспечить замену всего набора связанных аргументов шаблона с помощью std::hash<T> будучи шаблоном класса. Обратите внимание, что частичная перегрузка не помогает, потому что хэш-функцию нужно как-то указывать как объект, который нельзя сделать с помощью перегруженных функций (если к ним не обращаются через объект, но это то, что отличается от них).
  2. Неупорядоченные ассоциативные контейнеры параметризуются с помощью статической сущности (которую также можно динамически настраивать, если это поддерживает конкретный тип), что проще сделать с помощью шаблонов классов.
  3. Поскольку объекты, используемые для хэш-функции, можно настраивать, выбор между использованием типа или указателя функции для настройки. Указатели на функции часто трудно встроить, в то время как встроенные функции-члены типа тривиальны для встроенных, что значительно повышает производительность простых функций, таких как вычисление простого хэша.
17

Другие решения

Функция шаблона не могу быть частично специализированным для типов, в то время как std::hash специализированный для разных типов в качестве шаблона класса.

И таким способом, основанным на классах шаблонов, вы можете выполнять некоторые метапрограммирования, такие как доступ к типу возвращаемого значения и типу ключа, как показано ниже:

std::hash<X>::argument_type
std::hash<X>::result_type
4

По вопросам рекламы [email protected]