как заставить пользовательский тип работать как ключи в unordered_map - PullRequest
0 голосов
/ 15 октября 2018

Я пытаюсь получить настроенную хеш-таблицу, работающую с пользовательскими типами.Ссылаясь на ошибка конструктора unordered_map (шаблонная функция equal_to)

У меня есть:

typedef pair<int, int> tCoord;
struct hashing_func {
    unsigned long operator()(const tCoord& key) const {
        unsigned long hash = 0;
        int h1 = key.first;
        int h2 = key.second;
        return h1 ^ (h2 << 1);

    }
};

struct key_equal_fn {
    bool operator()(const tCoord& t1, const tCoord& t2) const {
        return t1.first == t2.first && t1.second == t2.second;
    }
};

unordered_map<tCoord, int, hashing_func, key_equal_fn> coord2cnt;
unordered_map<tCoord, int, hashing_func, key_equal_fn>::iterator iter;
iter = coord2cnt.find(coord);

Этот фрагмент не компилировался и жаловался на отсутствие вызова функции find ():

error: no matching member function for call to 'find'

Также пытался использовать его как coord2cnt[coord], но также получил ошибки при пропущенном операторе [].

Я компилирую с использованием g ++ 4.2, который немного староват, но прекрасно компилировал следующее (из ссылки выше):

typedef unordered_map<string, string, hashing_func, key_equal_fn> MapType;
MapType::size_type n = 5;
MapType mymap(n, hashing_func(), key_equal_fn());

Также интересно, почему этот тип определенияработа, т. е. указав 5 в первом параметре.Этот способ определения, по-видимому, отсутствует в API unordered_map ??

Кто-нибудь знает, что здесь пошло не так?Спасибо!

ОБНОВЛЕНИЕ: как уже указывалось, строка - это внутренний класс, который имеет встроенную хеш-функцию.Поэтому я перефразировал вопрос, чтобы использовать здесь настраиваемый тип.

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Unordered_map для строки как ключа обрабатывается внутренне.Вам не нужно определять хеш-функции для строки как ключи.

Если вы хотите передать класс или структуру в качестве ключа.Затем вам нужно определить хеш-функцию, чтобы он вычислял хеш-индекс для ключей, где коллизии минимальны.Чтобы найти структуру или объект класса с помощью .find, перегрузите оператор bool == в используемой структуре или классе.

Пример:

#include <iostream>
#include<unordered_map>
int main() {
  std::unordered_map<std::string, int> myMap;
  myMap.insert({"asd", 1});
  myMap.insert({"qwe", 2});
  std::string input;
  std::cout<<"Enter String: ";
  std::cin>>input;
  std::unordered_map<std::string, int>::iterator it = myMap.find(input);

  if(it != myMap.end())
    std::cout<<"Found";
  else
    std::cout<<"Not Found";
}
0 голосов
/ 15 октября 2018

Ваш пользовательский тип функции "key_equal_fn" - это [строка, строка], которая не совпадает с "text2cnt"

Если вы хотите сделать это в полностью специализированном шаблонном режиме, как это сделать:

template <typename T>
struct key_equal_fn {
    bool operator()(const T& t1, const T& t2) const {
        return t1==t2;
    }
};

template<>
struct key_equal_fn<string> {
    bool operator()(const string& t1, const string& t2) const {
        return !(t1.compare(t2));
    }
};

unordered_map<string, string, hashing_func, key_equal_fn<string> > text2cnt;
unordered_map<string, string, hashing_func, key_equal_fn<string> >::iterator iter;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...