I tried to switch from std::unordered_map (VS2010) to boost::unordered_map (version 1.48) and surprisingly, some important test cases failed in my project. I tracked down the cause and come to the conclusion that boost::unordered_map does not honor my case insensitive equality provider:
struct StringEqualityCaseInsensitive : public std::equal_to<String>
{
bool operator ()(const String& a, const String& b) const { return boost::iequals<String, String>(a, b); }
};
boost::unordered_map<string, int, boost::hash<string>, StringEqualityCaseInsensitive> map;
Now I just add some uppercase elements and search for their lowercase counterparts (using the find() member method). If I use the std::unordered_map it works just fine and with boost it doesn't. The cruel thing is that if I look for uppercase elements, the equality comparator gets invoked and when I look for lowercase, it doesn't get invoked...
Anyone's got a clue, why is this? (Not sure if this is important but I am using the Intel Compiler 12.1 with C++0x support enabled)
EDIT: Damn, now it dawns on me. Maybe I need to also adjust the hash class to return the same value independently of lower/upper-case. But still its strange that they have different behaviour?!
Thanks!
I doubt it will work in either boost::unordered_map
or std::unordered_map
, because your hash function is defined wrongly. The default boost::hash<string>
is not case insensitive, meaning one of the fundamental assumption of hash tables
a == b => hash(a) == hash(b)
is broken (i.e. HELLO
and hello
could generate different hashes). The two maps give different result is just an implementation detail.