Skip to content

Commit ad8d3f6

Browse files
authored
Update 003_stl_std_hash_std_string.cpp
1 parent cfd4410 commit ad8d3f6

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed
Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,59 @@
1-
1
1+
#include <iostream>
2+
#include <iomanip>
3+
#include <functional>
4+
#include <string>
5+
#include <unordered_set>
6+
7+
struct S {
8+
std::string first_name;
9+
std::string last_name;
10+
};
11+
bool operator==(const S& lhs, const S& rhs) {
12+
return lhs.first_name == rhs.first_name && lhs.last_name == rhs.last_name;
13+
}
14+
15+
// custom hash can be a standalone function object:
16+
struct MyHash
17+
{
18+
std::size_t operator()(S const& s) const noexcept
19+
{
20+
std::size_t h1 = std::hash<std::string>{}(s.first_name);
21+
std::size_t h2 = std::hash<std::string>{}(s.last_name);
22+
return h1 ^ (h2 << 1); // or use boost::hash_combine (see Discussion)
23+
}
24+
};
25+
26+
// custom specialization of std::hash can be injected in namespace std
27+
namespace std
28+
{
29+
template<> struct hash<S>
30+
{
31+
std::size_t operator()(S const& s) const noexcept
32+
{
33+
std::size_t h1 = std::hash<std::string>{}(s.first_name);
34+
std::size_t h2 = std::hash<std::string>{}(s.last_name);
35+
return h1 ^ (h2 << 1); // or use boost::hash_combine
36+
}
37+
};
38+
}
39+
40+
int main()
41+
{
42+
std::string str = "Meet the new boss...";
43+
std::size_t str_hash = std::hash<std::string>{}(str);
44+
std::cout << "hash(" << std::quoted(str) << ") = " << str_hash << '\n';
45+
46+
S obj = { "Hubert", "Farnsworth" };
47+
// using the standalone function object
48+
std::cout << "hash(" << std::quoted(obj.first_name) << ", "
49+
<< std::quoted(obj.last_name) << ") = "
50+
<< MyHash{}(obj) << " (using MyHash)\n" << std::setw(31) << "or "
51+
<< std::hash<S>{}(obj) << " (using injected std::hash<S> specialization)\n";
52+
53+
// custom hash makes it possible to use custom types in unordered containers
54+
// The example will use the injected std::hash<S> specialization above,
55+
// to use MyHash instead, pass it as a second template argument
56+
std::unordered_set<S> names = {obj, {"Bender", "Rodriguez"}, {"Turanga", "Leela"} };
57+
for(auto& s: names)
58+
std::cout << std::quoted(s.first_name) << ' ' << std::quoted(s.last_name) << '\n';
59+
}

0 commit comments

Comments
 (0)