Reputation: 5377
I'd like to store in map objects wrapping network connections, where key should be IP address + port number.
My question is how should I handle such key with two elements?
I can define std::unordered_map<std::pair<std::string, uint16_t>, Connection>
, but I'm not sure how should I implement hash object for it. Only naive implementation comes to my mind:
std::size_t operator() (const pair<std::string, uint16_t>& key) const
{
std::hash<std::string> ip_hash;
std::hash<uint16_t> port_hash;
return ip_hash (key.first) + port_hash (port.second);
}
I assume that simple addition of two hash values is rather bad idea. Are there any general rules that i should obey to when implementing hash functions?
(I know, that i can build a string from IP address and port number, but I'm just curious).
Upvotes: 3
Views: 641
Reputation: 7960
Your hashing is mostly fine for non security practices. You can make it more robust this way:
struct ip_port_hash
{
size_t operator() (const std::pair< std::string, uint16_t >& key) const
{
std::hash<const char*> ip_hash;
std::hash<size_t> size_t_hash;
return size_t_hash( ip_hash (key.first.c_str()) + key.second);
}
};
Upvotes: 0
Reputation: 1260
A trivial solution will be to append the uint16_t port number to the string, representing the IP address. Then you can use std:unordered_map<string, Connection>
.
Upvotes: 1
Reputation: 109119
If using boost is an option, boost::hash_combine
makes this really easy (otherwise the implementation is available on the linked page).
std::size_t operator()(const pair<std::string, uint16_t>& key) const
{
std::size_t seed = 0;
boost::hash_combine(seed, key.first);
boost::hash_combine(seed, key.second);
return seed;
}
Upvotes: 1