summaryrefslogtreecommitdiff
path: root/doc/html/boost_typeerasure/multi.html
blob: 7ecac3dbfa3172c99b9ab9961cd5ea206913c0da (plain)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Functions with Multiple Arguments</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../boost_typeerasure.html" title="Chapter&#160;33.&#160;Boost.TypeErasure">
<link rel="prev" href="composing_concepts.html" title="Composing Concepts">
<link rel="next" href="concept.html" title="Concepts in Depth">
</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="composing_concepts.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_typeerasure.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="concept.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="boost_typeerasure.multi"></a><a class="link" href="multi.html" title="Functions with Multiple Arguments">Functions with Multiple Arguments</a>
</h2></div></div></div>
<p>
      (For the source of the examples in this section see <a href="../../../libs/type_erasure/example/multi.cpp" target="_top">multi.cpp</a>)
    </p>
<p>
      Operations can have more than one <code class="computeroutput"><a class="link" href="../boost/type_erasure/any.html" title="Class template any">any</a></code>
      argument. Let's use binary addition as an example.
    </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">any</span><span class="special">&lt;</span>
    <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>
        <span class="identifier">copy_constructible</span><span class="special">&lt;&gt;,</span>
        <span class="identifier">typeid_</span><span class="special">&lt;&gt;,</span>
        <span class="identifier">addable</span><span class="special">&lt;&gt;,</span>
        <span class="identifier">ostreamable</span><span class="special">&lt;&gt;</span>
    <span class="special">&gt;</span>
<span class="special">&gt;</span> <span class="identifier">any_type</span><span class="special">;</span>
<span class="identifier">any_type</span> <span class="identifier">x</span><span class="special">(</span><span class="number">10</span><span class="special">);</span>
<span class="identifier">any_type</span> <span class="identifier">y</span><span class="special">(</span><span class="number">7</span><span class="special">);</span>
<span class="identifier">any_type</span> <span class="identifier">z</span><span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">z</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> <span class="comment">// prints 17</span>
</pre>
<p>
    </p>
<p>
      This is <span class="emphasis"><em>not</em></span> a multimethod. The underlying types of the
      arguments of <code class="computeroutput"><span class="special">+</span></code> must be the same
      or the behavior is undefined. This example is correct because the arguments
      both hold <code class="computeroutput"><span class="keyword">int</span></code>'s.
    </p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
        Adding <code class="computeroutput"><a class="link" href="../boost/type_erasure/relaxed.html" title="Struct relaxed">relaxed</a></code>
        leads an exception rather than undefined behavior if the argument types are
        wrong.
      </p></td></tr>
</table></div>
<p>
      <code class="computeroutput"><a class="link" href="../boost/type_erasure/addable.html" title="Struct template addable">addable</a></code><code class="computeroutput"><span class="special">&lt;&gt;</span></code> requires the types of the arguments
      to be exactly the same. This doesn't cover all uses of addition though. For
      example, pointer arithmetic takes a pointer and an integer and returns a pointer.
      We can capture this kind of relationship among several types by identifying
      each type involved with a placeholder. We'll let the placeholder <code class="computeroutput"><span class="identifier">_a</span></code> represent the pointer and the placeholder
      <code class="computeroutput"><span class="identifier">_b</span></code> represent the integer.
    </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">array</span><span class="special">[</span><span class="number">5</span><span class="special">];</span>

<span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span>
    <span class="identifier">copy_constructible</span><span class="special">&lt;</span><span class="identifier">_a</span><span class="special">&gt;,</span>
    <span class="identifier">copy_constructible</span><span class="special">&lt;</span><span class="identifier">_b</span><span class="special">&gt;,</span>
    <span class="identifier">typeid_</span><span class="special">&lt;</span><span class="identifier">_a</span><span class="special">&gt;,</span>
    <span class="identifier">addable</span><span class="special">&lt;</span><span class="identifier">_a</span><span class="special">,</span> <span class="identifier">_b</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">&gt;</span>
<span class="special">&gt;</span> <span class="identifier">requirements</span><span class="special">;</span>
</pre>
<p>
    </p>
<p>
      Our new concept, <code class="computeroutput"><span class="identifier">addable</span><span class="special">&lt;</span><span class="identifier">_a</span><span class="special">,</span> <span class="identifier">_b</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">&gt;</span></code>
      captures the rules of pointer addition: <code class="computeroutput"><span class="identifier">_a</span>
      <span class="special">+</span> <span class="identifier">_b</span> <span class="special">-&gt;</span> <span class="identifier">_a</span></code>.
    </p>
<p>
      Also, we can no longer capture the variables independently.
</p>
<pre class="programlisting"><span class="identifier">any</span><span class="special">&lt;</span><span class="identifier">requirements</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">&gt;</span> <span class="identifier">ptr</span><span class="special">(&amp;</span><span class="identifier">array</span><span class="special">[</span><span class="number">0</span><span class="special">]);</span> <span class="comment">// illegal</span>
</pre>
<p>
      This doesn't work because the library needs to know the type that _b binds
      to when it captures the concept bindings. We need to specify the bindings of
      both placeholders when we construct the <code class="computeroutput"><a class="link" href="../boost/type_erasure/any.html" title="Class template any">any</a></code>.
    </p>
<p>
</p>
<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">map</span><span class="special">&lt;</span><span class="identifier">mpl</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">_a</span><span class="special">,</span> <span class="keyword">int</span><span class="special">*&gt;,</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">_b</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">types</span><span class="special">;</span>
<span class="identifier">any</span><span class="special">&lt;</span><span class="identifier">requirements</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">&gt;</span> <span class="identifier">ptr</span><span class="special">(&amp;</span><span class="identifier">array</span><span class="special">[</span><span class="number">0</span><span class="special">],</span> <span class="identifier">make_binding</span><span class="special">&lt;</span><span class="identifier">types</span><span class="special">&gt;());</span>
<span class="identifier">any</span><span class="special">&lt;</span><span class="identifier">requirements</span><span class="special">,</span> <span class="identifier">_b</span><span class="special">&gt;</span> <span class="identifier">idx</span><span class="special">(</span><span class="number">2</span><span class="special">,</span> <span class="identifier">make_binding</span><span class="special">&lt;</span><span class="identifier">types</span><span class="special">&gt;());</span>
<span class="identifier">any</span><span class="special">&lt;</span><span class="identifier">requirements</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">&gt;</span> <span class="identifier">x</span><span class="special">(</span><span class="identifier">ptr</span> <span class="special">+</span> <span class="identifier">idx</span><span class="special">);</span>
<span class="comment">// x now holds array + 2</span>
</pre>
<p>
    </p>
<p>
      Now that the arguments of <code class="computeroutput"><span class="special">+</span></code> aren't
      the same type, we require that both arguments agree that <code class="computeroutput"><span class="identifier">_a</span></code>
      maps to <code class="computeroutput"><span class="keyword">int</span><span class="special">*</span></code>
      and that <code class="computeroutput"><span class="identifier">_b</span></code> maps to <code class="computeroutput"><span class="keyword">int</span></code>.
    </p>
<p>
      We can also use <code class="computeroutput"><a class="link" href="../boost/type_erasure/tuple.html" title="Class template tuple">tuple</a></code>
      to avoid having to write out the map out explicitly. <code class="computeroutput"><a class="link" href="../boost/type_erasure/tuple.html" title="Class template tuple">tuple</a></code>
      is just a convenience class that combines the placeholder bindings it gets
      from all its arguments.
    </p>
<p>
</p>
<pre class="programlisting"><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">requirements</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">,</span> <span class="identifier">_b</span><span class="special">&gt;</span> <span class="identifier">t</span><span class="special">(&amp;</span><span class="identifier">array</span><span class="special">[</span><span class="number">0</span><span class="special">],</span> <span class="number">2</span><span class="special">);</span>
<span class="identifier">any</span><span class="special">&lt;</span><span class="identifier">requirements</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">&gt;</span> <span class="identifier">y</span><span class="special">(</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">t</span><span class="special">));</span>
</pre>
<p>
    </p>
</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 &#169; 2011-2013 Steven Watanabe<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="composing_concepts.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../boost_typeerasure.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="concept.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>