MyClass
определяет operator==
и имеет нетривиальное внутреннее состояние, но оно обеспечивает wstring toString()
метод, который возвращает сериализованную версию этого состояния. Поэтому я подумал, что будет просто использовать toString()
с hash<wstring>
на std::unordered_set
,
Но возможно ли сделать это аккуратно, без определения посторонних классов функторов? Я только начинаю разбираться с C ++ 11 после перехода на VS2013, и я подумал, что это был один из больших шагов вперед, возможность определить такие вещи, как лямбды?
Спасибо за любые предложения, как лучше всего это сделать.
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);
Лучший подход — это сказать 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
,