我的类有一个toString()方法,如何在std :: unordered_set中使用它进行散列?

时间:2014-10-09 15:54:14

标签: c++ visual-studio c++11 visual-c++-2013

MyClass定义operator==并且具有非平凡的内部状态,但它确实提供了wstring toString()方法,该方法返回该状态的序列化版本。所以我认为在toString() hash<wstring> std::unordered_set上使用{{1}}会很容易。

但是,如果不定义无关的函子类,是否可以以一种漂亮的方式执行此操作?在转向VS2013之后我才刚刚接触到C ++ 11,我认为这是向前迈出的重要一步,能够定义像lambdas这样的东西吗?

感谢您提供最好的建议。

2 个答案:

答案 0 :(得分:3)

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

不幸的是,目前这不适用于MSVC due to a bug

可能的解决方法包括为std::hash编写MyClass的特化,或将lambda存储在std::function<std::size_t(const MyClass &)>中并将其用作hasher的类型:

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);

答案 1 :(得分:0)

最好的方法是告诉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_setunordered_map的非默认模板参数而烦恼。