1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Extending boost::hash for a custom data type</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../hash.html" title="Chapter 15. Boost.Functional/Hash">
<link rel="prev" href="tutorial.html" title="Tutorial">
<link rel="next" href="combine.html" title="Combining hash values">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../hash.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="combine.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="hash.custom"></a><a class="link" href="custom.html" title="Extending boost::hash for a custom data type">Extending boost::hash for a custom data type</a>
</h2></div></div></div>
<p>
<code class="computeroutput"><a class="link" href="../boost/hash.html" title="Struct template hash">boost::hash</a></code> is implemented by calling
the function <code class="computeroutput"><a class="link" href="reference.html#boost.hash_value_idp510000592">hash_value</a></code>.
The namespace isn't specified so that it can detect overloads via argument
dependant lookup. So if there is a free function <code class="computeroutput"><span class="identifier">hash_value</span></code>
in the same namespace as a custom type, it will get called.
</p>
<p>
If you have a structure <code class="computeroutput"><span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span></code>, where
each <code class="computeroutput"><span class="identifier">book</span></code> is uniquely defined
by it's member <code class="computeroutput"><span class="identifier">id</span></code>:
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">library</span>
<span class="special">{</span>
<span class="keyword">struct</span> <span class="identifier">book</span>
<span class="special">{</span>
<span class="keyword">int</span> <span class="identifier">id</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">author</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">title</span><span class="special">;</span>
<span class="comment">// ....</span>
<span class="special">};</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">book</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">a</span><span class="special">,</span> <span class="identifier">book</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">b</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">a</span><span class="special">.</span><span class="identifier">id</span> <span class="special">==</span> <span class="identifier">b</span><span class="special">.</span><span class="identifier">id</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
Then all you would need to do is write the function <code class="computeroutput"><span class="identifier">library</span><span class="special">::</span><span class="identifier">hash_value</span></code>:
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">library</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">hash_value</span><span class="special">(</span><span class="identifier">book</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">b</span><span class="special">)</span>
<span class="special">{</span>
<code class="computeroutput"><a class="link" href="../boost/hash.html" title="Struct template hash">boost::hash</a></code><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">hasher</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">hasher</span><span class="special">(</span><span class="identifier">b</span><span class="special">.</span><span class="identifier">id</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
And you can now use <code class="computeroutput"><a class="link" href="../boost/hash.html" title="Struct template hash">boost::hash</a></code> with
book:
</p>
<pre class="programlisting"><span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span> <span class="identifier">knife</span><span class="special">(</span><span class="number">3458</span><span class="special">,</span> <span class="string">"Zane Grey"</span><span class="special">,</span> <span class="string">"The Hash Knife Outfit"</span><span class="special">);</span>
<span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span> <span class="identifier">dandelion</span><span class="special">(</span><span class="number">1354</span><span class="special">,</span> <span class="string">"Paul J. Shanley"</span><span class="special">,</span>
<span class="string">"Hash & Dandelion Greens"</span><span class="special">);</span>
<code class="computeroutput"><a class="link" href="../boost/hash.html" title="Struct template hash">boost::hash</a></code><span class="special"><</span><span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span><span class="special">></span> <span class="identifier">book_hasher</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">knife_hash_value</span> <span class="special">=</span> <span class="identifier">book_hasher</span><span class="special">(</span><span class="identifier">knife</span><span class="special">);</span>
<span class="comment">// If std::unordered_set is available:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">unordered_set</span><span class="special"><</span><span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/hash.html" title="Struct template hash">boost::hash</a></code><span class="special"><</span><span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span><span class="special">></span> <span class="special">></span> <span class="identifier">books</span><span class="special">;</span>
<span class="identifier">books</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">knife</span><span class="special">);</span>
<span class="identifier">books</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span><span class="special">(</span><span class="number">2443</span><span class="special">,</span> <span class="string">"Lindgren, Torgny"</span><span class="special">,</span> <span class="string">"Hash"</span><span class="special">));</span>
<span class="identifier">books</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="identifier">library</span><span class="special">::</span><span class="identifier">book</span><span class="special">(</span><span class="number">1953</span><span class="special">,</span> <span class="string">"Snyder, Bernadette M."</span><span class="special">,</span>
<span class="string">"Heavenly Hash: A Tasty Mix of a Mother's Meditations"</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">books</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">knife</span><span class="special">)</span> <span class="special">!=</span> <span class="identifier">books</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">books</span><span class="special">.</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">dandelion</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">books</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
</pre>
<p>
The full example can be found in: <a href="../../../libs/functional/hash/examples/books.hpp" target="_top">/libs/functional/hash/examples/books.hpp</a>
and <a href="../../../libs/functional/hash/examples/books.cpp" target="_top">/libs/functional/hash/examples/books.cpp</a>.
</p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
When writing a hash function, first look at how the equality function works.
Objects that are equal must generate the same hash value. When objects are
not equal they should generate different hash values. In this object equality
was based just on the id so the hash function only hashes the id. If it was
based on the object's name and author then the hash function should take
them into account (how to do this is discussed in the next section).
</p></td></tr>
</table></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2005-2008 Daniel
James<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../hash.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="combine.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
|