В моем классе есть метод toString (), как мне использовать это для хеширования в std :: unordered_set?

MyClass определяет operator== и имеет нетривиальное внутреннее состояние, но оно обеспечивает wstring toString() метод, который возвращает сериализованную версию этого состояния. Поэтому я подумал, что будет просто использовать toString() с hash<wstring> на std::unordered_set,

Но возможно ли сделать это аккуратно, без определения посторонних классов функторов? Я только начинаю разбираться с C ++ 11 после перехода на VS2013, и я подумал, что это был один из больших шагов вперед, возможность определить такие вещи, как лямбды?

Спасибо за любые предложения, как лучше всего это сделать.

1

Решение

auto hasher = [](const MyClass &m){ return std::hash<std::wstring>()(m.toString()); };
std::unordered_set<MyClass, decltype(hasher)> set(10, hasher);

К сожалению, в настоящее время это не работает с MSVC из-за ошибки.

Возможные обходные пути включают написание специализации std::hash за MyClassили хранение лямбда в std::function<std::size_t(const MyClass &)> и используйте это как тип хеша:

std::function<std::size_t(const MyClass &)> hasher =
[](const MyClass &m) { return std::hash<std::wstring>()(m.toString()); };
std::unordered_set<MyClass, std::function<std::size_t(const MyClass &)>> set(10, hasher);
3

Другие решения

Лучший подход — это сказать std::hash как хешировать MyClass по специализации:

namespace std {
template <>
struct hash<MyClass> {
std::size_t operator () (const MyClass& mc) const {
return std::hash<std::wstring>()(mc.toString());
}
};
} // namespace std

так что вам не нужно беспокоиться о нестандартных параметрах шаблона для unordered_set или же unordered_map,

0

По вопросам рекламы [email protected]