Intereting Posts
Используется ли FC ++ для любых проектов с открытым исходным кодом? C ++: Как разбить строку на меньшие строки меньшего размера? Почему компиляция не выполняется, когда имя параметра шаблона совпадает с именем внутреннего classа? Как уменьшить размер выходного кода на C32-шаблоне? Форматирование вывода в C ++ Различные операторы литья, вызываемые разными компиляторами Разрешение перегрузки в пространстве имен size () Vs empty () в векторе – почему пустым () является предпочтительным? как выполнить тест производительности с использованием библиотеки boost для пользовательской библиотеки Почему невозможно переопределить оператор << для classов шаблонов с использованием стороннего кода? Первое случайное число всегда меньше, чем остальные Указатель на член, который является ссылкой незаконным? Копировать конструктор, необходимый с помощью временного объекта Как отсортировать элементы в C ++-матрице? Зачем использовать бесконечные петли?

std :: unordered_map и ключ, построенный из нескольких элементов

Я хотел бы сохранить в объектах карты, обертывающих сетевые подключения, где ключ должен быть IP-адресом + номер порта.

Мой вопрос: как мне обращаться с таким ключом с двумя элементами?

Я могу определить std::unordered_map<std::pair, Connection> , но я не уверен, как мне реализовать hash-объект для него. Мне приходит в голову только наивная реализация:

 std::size_t operator() (const pair& key) const { std::hash ip_hash; std::hash port_hash; return ip_hash (key.first) + port_hash (port.second); } 

Я предполагаю, что простое добавление двух hash-значений – довольно плохая идея. Существуют ли какие-либо общие правила, которым я должен подчиняться при реализации хеш-функций?

(Я знаю, что я могу построить строку из IP-адреса и номера порта, но мне просто интересно).

Если использовать boost – опция, boost::hash_combine делает это очень просто (иначе реализация доступна на связанной странице).

 std::size_t operator()(const pair& key) const { std::size_t seed = 0; boost::hash_combine(seed, key.first); boost::hash_combine(seed, key.second); return seed; } 

Тривиальным решением будет добавить номер порта uint16_t в строку, представляющую IP-адрес. Затем вы можете использовать std:unordered_map .

Ваше хеширование в основном прекрасное для небезопасных методов. Вы можете сделать его более устойчивым таким образом:

 struct ip_port_hash { size_t operator() (const std::pair< std::string, uint16_t >& key) const { std::hash ip_hash; std::hash size_t_hash; return size_t_hash( ip_hash (key.first.c_str()) + key.second); } };