Search code examples
c++boostcase-insensitiveunordered-map

C++: Case insensitive "Boost:unordered_map" does not work?


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!


Solution

  • 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.