Является ли std::hash одинаковым во всех дистрибутивах stdlib?
Если бы я сделал std::hash
с помощью libstdc++
а затем сделал один на предстоящем C++11
Библиотека VS 2012 - будут ли они соответствовать?
Я предполагаю, что хэш-реализации не являются частью спецификации C++ и могут варьироваться в зависимости от распределения?
3 ответа
Стандарт говорит только это:
20.8.12 Хэш шаблона класса Неупорядоченные ассоциативные контейнеры, определенные в 23.5, используют специализации хэша шаблона класса в качестве хэш-функции по умолчанию. Для всех типов объектов Key, для которых существует хеш-специализация, хеш-экземпляр должен:
- удовлетворить требования Hash (17.6.3.4), с ключом в качестве типа аргумента вызова функции, требованиями DefaultConstructible (таблица 19), требованиями CopyAssignable (таблица 23),
- быть замененным (17.6.3.2) для lvalues,
- предоставить два вложенных типа result_type и arguments_type, которые должны быть синонимами для size_t и Key соответственно,
- удовлетворяют требованию, что если k1 == k2 истинно, h(k1) == h(k2) также истинно, где h - объект типа hash, а k1 и k2 - объекты типа Key.
в 17.6.3.4 это наиболее важно (таблица 26):
Не будет бросать исключения. Возвращаемое значение должно зависеть только от аргумента k. [Примечание: Таким образом, все вычисления выражения h(k) с одним и тем же значением для k дают одинаковый результат. - примечание конца] [Примечание: для двух разных значений t1 и t2 вероятность того, что h(t1) и h(t2) сравнятся одинаково, должна быть очень мала, приближаясь к 1,0 / numeric_- limit::max(). - конец примечания]
Таким образом, в общем, нет, само вычисление не определено, и результат не обязательно должен быть согласованным с реализациями. В этом отношении даже две разные версии одной и той же библиотеки могут давать разные результаты.
Нет, это не гарантировано. std::hash
только должен соблюдать следующие условия:
- Принимает один параметр типа Key.
- Возвращает значение типа size_t, представляющее хеш-значение параметра.
- Не выдает исключений при вызове.
- Для двух одинаковых параметров k1 и k2 std::hash()(k1) == std::hash()(k2).
- Для двух разных параметров k1 и k2, которые не равны, вероятность того, что std:: hash () (k1) == std:: hash () (k2) должна быть очень мала, приближаясь к 1.0 / std:: numeric_limits:: max ().
Требования (17.6.3.4 Хеш-требования [hash.requirements]) к значению, возвращаемому Hash
функции являются:
Таблица 26 - Требования к хешу [хеш]
Возвращаемое значение должно зависеть только от аргумента
k
, [Примечание: Таким образом, все оценки выраженияh(k)
с тем же значением дляk
дать тот же результат. - конец примечания] [Примечание: для двух разных значенийt1
а такжеt2
вероятность того, чтоh(t1)
а такжеh(t2)
сравнивать равных надо очень мало, приближаясь1.0 / numeric_limits<size_t>::max()
, —Конечная записка]
На практике это довольно распространено, что для целочисленных типов std::hash(k)
будет равно k
Это самая простая реализация, соответствующая стандарту. Для других типов все возможно.