Хэш-функция для пользовательского класса. Как подружиться?:)
У меня есть класс C, у которого есть частный элемент данных string* ps
.
Теперь я хотел бы иметь unordered_map<C, int>
, для которого мне нужна пользовательская хеш-функция.
В соответствии с ссылкой на С++, я могу сделать это как
namespace std {
template<>
class hash<C> {
public:
size_t operator()(const C &c) const
{
return std::hash<std::string>()(*c.ps);
}
};
}
Проблема в том, что я не могу заставить друзей operator()
и C
так, чтобы я мог получить доступ к ps
.
Я пробовал это:
class C;
template<>
class std::hash<C>;
class C{
//...
friend std::hash<C>::operator ()(const C&) const; // error: Incomplete type
};
// define hash<C> here.
но он говорит, что неполный тип... в вложенном спецификаторе имен...
Я тоже не могу обойти определения, потому что, если класс C определяется позже, hash<C>
не имеет возможности узнать о ps
.
Что я здесь делаю неправильно? Как можно зафиксировать эту ситуацию, не делая ps
public?
Ответы
Ответ 1
Попробуйте следующее:
class C;
namespace std {
template<>
class hash<C> {
public:
size_t operator()(const C &c) const; // don't define yet
};
}
class C{
//...
friend std::hash<C>::operator ()(const C&) const;
};
namespace std {
template<>
size_t hash<C>::operator()(const C &c) const {
return std::hash<std::string>()(*c.ps);
}
}
Или это:
class C;
template<>
class std::hash<C>;
class C{
friend class std::hash<C>; // friend the class, not the member function
};
(я не скомпилирован, поэтому может возникнуть синтаксическая ошибка)
Ответ 2
Я бы предложил добавить метод, например, следующий
class C
{
....
public: const string* get_ps() const { return ps; }
....
};
и использовать его в своей хэш-специализации.