std::hash的要求如下:(http://en.cppreference.com/w/cpp/utility/hash)
哈希模板定义了一个实现哈希函数的函数对象。该函数对象的实例满足 Hash。特别是,他们定义了一个 operator():
- 接受
Key 类型的单个参数。
- 返回一个
size_t 类型的值,表示参数的哈希值。
- 调用时不抛出异常。
- 对于两个相等的参数
k1 和k2,std::hash<Key>()(k1) == std::hash<Key>()(k2)。
- 对于两个不同的参数
k1和k2不相等,std::hash<Key>()(k1) == std::hash<Key>()(k2)的概率应该很小,接近1.0 / std::numeric_limits<size_t>::max()。
哈希模板既是CopyConstructible又是Destructible。
所以你需要的基本上是一个函数,它返回一个std::size_t,它对于每个myStruct 对象都是唯一的,并且对于被认为是等效的对象返回相同的值。
编辑:以下可能不是生成哈希的最可靠的方法,但它将作为如何完成它的基本示例。
一种方法是使用 std::hash<std::string> 的标准特化,通过使用 分隔符序列 连接每个 std::set 成员中的所有字符串,然后将所有生成的合并字符串连接成一个并使用标准哈希函数返回哈希值。
如果成员 std::sets 不同,则合并的“超级”字符串对于每个 myStruct 对象都是唯一的,并且当成员不不同时仍然相同,因为 std::set 是有序容器。
struct myStruct {
std::set<std::string> s1;
std::set<std::string> s2;
};
std::string mergeAllStrings(const myStruct& ms) {
static const std::string SEPARATOR = "#¤%&"; // Some uncommon sequence.
std::string super;
for (const auto& s : ms.s1) {
super += s + SEPARATOR; // Append separator.
}
for (const auto& s : ms.s2) {
super += s + SEPARATOR; // Append separator.
}
return super;
}
int main() {
myStruct ms1{{"apple", "pear", "orange"}, {"red", "green", "blue"}};
myStruct ms2{{"pear", "apple", "orange"}, {"red", "green", "blue"}};
myStruct ms3{{"apple", "banana", "orange"}, {"red", "green", "blue"}};
std::cout << std::hash<std::string>()(mergeAllStrings(ms1)) << std::endl;
std::cout << std::hash<std::string>()(mergeAllStrings(ms2)) << std::endl;
std::cout << std::hash<std::string>()(mergeAllStrings(ms3)) << std::endl;
}
输出:
2681724430859750844 // Same
2681724430859750844 // Same
2942368903851914580 // Different
您现在可以创建一个哈希函子,例如如:
struct MyHash {
std::size_t operator()(const myStruct& ms) const {
return std::hash<std::string>()(mergeAllStrings(ms));
}
};
并将其与std::unordered_map 一起使用:
std::unordered_map<myStruct, myValue, MyHash> m;
请注意,您还应该提供自定义的 equal_to 函子。