//
//
namespace std {
template <> //
struct hash
{
//
//
typedef size_t result_type;
typedef Sales_data argument_type; //
//
size_t operator()(const Sales_data& s) const;
//
//
};
size_t
hash
return hash
hash
hash
}
} //
//
Определение hash начинается с части template<>, означающей, что определяется полностью специализированный шаблон. Специализируемый шаблон называется hash, а специализированная версия — hash. Члены класса следуют непосредственно из требований для специализации шаблона hash.
Подобно любым другим классам, специализируемые члены можно определить в классе или вне его, как это сделано здесь. Перегруженный оператор вызова должен определять хеш-функцию по значениям заданного типа. Эта функция обязана возвращать каждый раз тот же результат, когда она вызывается для данного значения. Хеш-функция практически всегда возвращает другой результат для не равных объектов.
Все сложности определения хорошей хеш-функции делегируем библиотеке. Библиотека определяет специализации класса hash для встроенных типов и для большинства библиотечных типов. Безымянный объект hash используется для создания хеш-кода для переменной-члена bookNo, объект типа hash для создания хеш-кода из переменной-члена units_sold и объекта типа hash для создания хеш-кода из переменной-члена revenue. Применение к этим результатам оператора исключающего ИЛИ (см. раздел 4.8) сформирует общий хеш-код для заданного объекта класса Sales_data.
Следует заметить, что хеш-функция определена для хеширования всех трех переменных-членов, чтобы она была совместима с определением оператора operator== класса Sales_data (см. раздел 14.3.1). По умолчанию неупорядоченные контейнеры используют специализацию хеша, соответствующую типу key_type, наряду с оператором равенства типа ключа.
С учетом того, что специализация находится в области видимости, она будет использоваться автоматически при использовании класса Sales_data как ключ в одном из этих контейнеров:
//
//
unordered_multiset
Поскольку hash использует закрытые члены класса Sales_data, этот класс следует сделать другом класса Sales_data:
template
//
class Sales_data {
friend class std::hash
//
};
Здесь указано, что специфический экземпляр hash является дружественным. Поскольку данный экземпляр определяется в пространстве имен std, следует помнить, что этот тип хеша определяется в пространстве имен std. Следовательно, объявление friend относится к std::hash.
Sales_data использовать специализацию шаблона hash, следует определить эту специализацию в заголовке Sales_data.
В отличие от шаблона функции, специализация шаблона класса не обязана предоставлять аргументы для каждого параметра шаблона. Можно определить некоторые из них, но не все.