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

C++ 我的类有一个toString()方法,如何在std::unordered_集中使用它进行散列?,c++,visual-studio,c++11,visual-c++-2013,C++,Visual Studio,C++11,Visual C++ 2013,MyClass定义了operator=并具有非平凡的内部状态,但它确实提供了一个wstring-toString()方法,该方法返回该状态的序列化版本。所以我认为只要在std::unordered\u set上使用toString()和hash就很容易了 但是,在不定义无关的函子类的情况下,是否有可能以一种简洁的方式实现这一点呢?在迁移到VS2013之后,我才刚刚开始接触C++11,我认为这是向前迈出的一大步,能够定义诸如lambdas之类的东西 感谢您提出的建议。最好的方法是通过专门化告诉st

MyClass
定义了
operator=
并具有非平凡的内部状态,但它确实提供了一个
wstring-toString()
方法,该方法返回该状态的序列化版本。所以我认为只要在
std::unordered\u set
上使用
toString()
hash
就很容易了

但是,在不定义无关的函子类的情况下,是否有可能以一种简洁的方式实现这一点呢?在迁移到VS2013之后,我才刚刚开始接触C++11,我认为这是向前迈出的一大步,能够定义诸如lambdas之类的东西


感谢您提出的建议。最好的方法是通过专门化告诉
std::hash
如何散列
MyClass

auto hasher = [](const MyClass &m){ return std::hash<std::wstring>()(m.toString()); };
std::unordered_set<MyClass, decltype(hasher)> set(10, hasher);
namespace std {
template <>
struct hash<MyClass> {
  std::size_t operator () (const MyClass& mc) const {
    return std::hash<std::wstring>()(mc.toString());
  }
};
} // namespace std
名称空间std{
模板
结构散列{
std::size\u t运算符()(const MyClass&mc)const{
返回std::hash()(mc.toString());
}
};
}//名称空间std

因此,您不需要为
unordered\u set
unordered\u map

设置非默认模板参数。奇怪的是,无论出于何种原因,似乎都需要提供
std::hash
的专门化。此外,该问题询问lambdas。@T.C.该问题询问“如何最好地执行此操作的建议”。毫无疑问,最好的方法是告诉标准库如何散列自定义类型,因此,声明或初始化无序映射和无序集不需要特殊处理。@T.C.17.6.3.4中哈希要求中缺少
result\u type
argument\u type
,这意味着该要求基于标准库提供的专门化,可能是针对希望将其作为一元函数处理的用户。我发现很难相信有一个病态的实现,例如无序_,它可以与任何散列一起正常工作,但明确声明它的散列器必须具有这些类型,当且仅当它是
std::Hash
专门化时。[unord.Hash]的最后一个项目符号明确豁免了用户定义的专门化-满足表达式
h(k)
的要求,其中
h
是类型
hash
的对象,
k
是类型
Key
的对象,除非
hash
是依赖于至少一个用户定义类型的用户定义专门化,否则表达式不应抛出异常“,所以我觉得其他要求适用于所有专业,无论是由图书馆还是用户提供的(尽管如果它确实提出了这样的要求,老实说,这听起来像是一个缺陷)。你能解释一下为什么需要
模板吗?我做了一些与这个答案非常相似的事情,它也能工作,但我根本没有使用模板,例如
struct hash{std::size\u t operator()(const MyClass&mc)…}
namespace std {
template <>
struct hash<MyClass> {
  std::size_t operator () (const MyClass& mc) const {
    return std::hash<std::wstring>()(mc.toString());
  }
};
} // namespace std