简体   繁体   中英

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!

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 (ie HELLO and hello could generate different hashes). The two maps give different result is just an implementation detail.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM