C ++: без учета регистра "Boost: unordered_map" не работает? - PullRequest
1 голос
/ 18 января 2012

Я попытался переключиться с std :: unordered_map (VS2010) на boost :: unordered_map (версия 1.48), и, что удивительно, некоторые важные тестовые примеры не сработали в моем проекте. Я выяснил причину и пришел к выводу, что boost :: unordered_map не учитывает мой поставщик равенства без учета регистра:

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;

Теперь я просто добавляю несколько прописных элементов и ищу их строчные буквы (используя метод find ()). Если я использую std :: unordered_map, он работает просто отлично, а с boost - нет. Жестоко то, что если я ищу прописные элементы, вызывается компаратор равенства, а когда я ищу строчные, он не вызывается ...

Кто-нибудь знает, почему это? (Не уверен, что это важно, но я использую Intel Compiler 12.1 с включенной поддержкой C ++ 0x)

РЕДАКТИРОВАТЬ: Черт, теперь меня осенило. Возможно, мне нужно также настроить класс хеш-функции, чтобы он возвращал одно и то же значение независимо от строчных и прописных букв. Но все же странно, что у них другое поведение ?!

Спасибо!

1 Ответ

8 голосов
/ 18 января 2012

Я сомневаюсь, что он будет работать в boost::unordered_map или std::unordered_map, потому что ваша хеш-функция определена неправильно.Значение по умолчанию boost::hash<string> равно , а не без учета регистра, что означает, что одно из фундаментальных допущений хеш-таблиц

a == b   =>   hash(a) == hash(b)

нарушено (т. Е. HELLO и hello могут генерировать разные хэши),Две карты дают разные результаты - это просто детали реализации.

...