的要求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
对象都是唯一的,并且对于被认为是等效的对象返回相同的值。
编辑:以下可能不是生成哈希的最可靠的方法,但它将作为如何完成它的基本示例。
一种方法是使用标准特化 for ,通过使用分隔符序列std::hash<std::string>
连接每个std::set
成员中的所有字符串,然后将所有生成的合并字符串连接成一个,并使用标准哈希函数返回哈希值。
如果成员不同,则合并的“超级”字符串对于每个myStruct
对象都是唯一的,并且当成员与有序容器std::set
不同时仍然相同。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
函子。