On Friday, October 13, 2017 at 10:07:27 AM UTC-5, Marcel Mueller wrote:
> On 13.10.17 16.49, Christopher Pisz wrote:
> > I want to use a custom structure for a key in an std::unordered_map. The compiler complains that C++ does not provide a hash function for that type. From what I can find in googling, I need to implement some manner of hash operator. Can someone help me with a small example?
> [...]
> > What do I need to do to use this as a key in std::unordered_map?
> >
> > I see
https://stackoverflow.com/questions/17016175/c-unordered-map-using-a-custom-class-type-as-the-key
SNIP
> The code in the first reply is exactly what yo need, i.e. the
> specialization of std::hash for your type. A typical implementation
> calls std::hash for each member and combines the result somehow.
>
>
> Marcel
So my attempt looks like this
#pragma once
// Standard Includes
#include <unordered_map>
#include <string>
//--------------------------------------------------------------------------------------------------
namespace MyNamespace
{
namespace Domain
{
//--------------------------------------------------------------------------------------------------
enum MyEnum
{
VAL_1,
VAL_2
};
//--------------------------------------------------------------------------------------------------
/// Contains information (that we care about) that identifies an XTend client.
/// These details are passed to the Mid Level when we make requests
struct __declspec(dllexport) MyClass
{
MyClass();
MyClass(const std::string & nonUniqueId
, bool isOn
, const MyEnum & myEnum);
~MyClass();
MyClass(const MyClass & rhs);
MyClass(const MyClass && rhs);
MyClass & operator = (const MyClass & rhs);
MyClass & operator = (const MyClass && rhs);
bool operator < (const MyClass & rhs) const;
bool operator == (const MyClass & rhs) const;
std::string m_nonUniqueId;
bool m_isOn;
MyEnum m_myEnum;
};
//--------------------------------------------------------------------------------------------------
} // End namespace
} // End namespace
//--------------------------------------------------------------------------------------------------
template<> struct std::hash<MyNamespace::Domain::MyClass>
{
typedef MyNamespace::Domain::MyClass argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const& s) const noexcept
{
result_type const h1(std::hash<std::string>{}(s.m_nonUniqueId));
result_type const h2(std::hash<bool>{}(s.m_isOn));
result_type const h3(std::hash<int>{}(s.m_myEnum));
return (h1 ^ (h2 << 1) ^ h3 << 2);
}
};
This line that I don't understand is
return (h1 ^ (h2 << 1) ^ h3 << 2);
^ is XOR and << is bit shift. Is this correct? If so, how does this contribute to my making a unique size_t or something that is close to unique? Can someone break that down a bit?