Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/doc/html/signals/tutorial.html @ 35

Last change on this file since 35 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 48.3 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4<title>Tutorial</title>
5<link rel="stylesheet" href="../boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
7<link rel="start" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
8<link rel="up" href="../signals.html" title="Chapter 12. Boost.Signals">
9<link rel="prev" href="../signals.html" title="Chapter 12. Boost.Signals">
10<link rel="next" href="reference.html" title="Reference">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%">
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
15<td align="center"><a href="../../../index.htm">Home</a></td>
16<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="../../../people/people.htm">People</a></td>
18<td align="center"><a href="../../../more/faq.htm">FAQ</a></td>
19<td align="center"><a href="../../../more/index.htm">More</a></td>
20</table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="../signals.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../signals.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../images/next.png" alt="Next"></a>
24</div>
25<div class="section" lang="en">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="signals.tutorial"></a>Tutorial</h2></div></div></div>
28<div class="toc"><dl>
29<dt><span class="section"><a href="tutorial.html#id1625926">How to Read this Tutorial</a></span></dt>
30<dt><span class="section"><a href="tutorial.html#id1625989">Compatibility Note</a></span></dt>
31<dt><span class="section"><a href="tutorial.html#id1626102">Hello, World! (Beginner)</a></span></dt>
32<dt><span class="section"><a href="tutorial.html#id1626257">Calling multiple slots</a></span></dt>
33<dt><span class="section"><a href="tutorial.html#id1626670">Passing values to and from slots</a></span></dt>
34<dt><span class="section"><a href="tutorial.html#id1627585">Connection Management</a></span></dt>
35<dt><span class="section"><a href="tutorial.html#id1628358">Example: Document-View</a></span></dt>
36<dt><span class="section"><a href="tutorial.html#id1628486">Linking against the Signals library</a></span></dt>
37</dl></div>
38<div class="section" lang="en">
39<div class="titlepage"><div><div><h3 class="title">
40<a name="id1625926"></a>How to Read this Tutorial</h3></div></div></div>
41<p>This tutorial is not meant to be read linearly. Its top-level
42structure roughly separates different concepts in the library
43(e.g., handling calling multiple slots, passing values to and from
44slots) and in each of these concepts the basic ideas are presented
45first and then more complex uses of the library are described
46later. Each of the sections is marked <span class="emphasis"><em>Beginner</em></span>,
47<span class="emphasis"><em>Intermediate</em></span>, or <span class="emphasis"><em>Advanced</em></span> to help guide the
48reader. The <span class="emphasis"><em>Beginner</em></span> sections include information that all
49library users should know; one can make good use of the Signals
50library after having read only the <span class="emphasis"><em>Beginner</em></span> sections. The
51<span class="emphasis"><em>Intermediate</em></span> sections build on the <span class="emphasis"><em>Beginner</em></span>
52sections with slightly more complex uses of the library. Finally,
53the <span class="emphasis"><em>Advanced</em></span> sections detail very advanced uses of the
54Signals library, that often require a solid working knowledge of
55the <span class="emphasis"><em>Beginner</em></span> and <span class="emphasis"><em>Intermediate</em></span> topics; most users
56will not need to read the <span class="emphasis"><em>Advanced</em></span> sections.</p>
57</div>
58<div class="section" lang="en">
59<div class="titlepage"><div><div><h3 class="title">
60<a name="id1625989"></a>Compatibility Note</h3></div></div></div>
61<p>Boost.Signals has two syntactical forms: the preferred form and
62the compatibility form. The preferred form fits more closely with the
63C++ language and reduces the number of separate template parameters
64that need to be considered, often improving readability; however, the
65preferred form is not supported on all platforms due to compiler
66bugs. The compatible form will work on all compilers supported by
67Boost.Signals. Consult the table below to determine which syntactic
68form to use for your compiler. Users of Boost.Function, please note
69that the preferred syntactic form in Signals is equivalent to that of
70Function's preferred syntactic form.</p>
71<p>If your compiler does not appear in this list, please try the
72preferred syntax and report your results to the Boost list so that
73we can keep this table up-to-date.</p>
74<div class="informaltable"><table class="table">
75<colgroup>
76<col>
77<col>
78</colgroup>
79<thead><tr>
80<th align="left">Preferred syntax</th>
81<th align="left">Portable syntax</th>
82</tr></thead>
83<tbody><tr>
84<td align="left">
85            <div class="itemizedlist"><ul type="disc">
86<li><p>GNU C++ 2.95.x, 3.0.x, 3.1.x</p></li>
87<li><p>Comeau C++ 4.2.45.2</p></li>
88<li><p>SGI MIPSpro 7.3.0</p></li>
89<li><p>Intel C++ 5.0, 6.0</p></li>
90<li><p>Compaq's cxx 6.2</p></li>
91<li><p>Microsoft Visual C++ 7.1</p></li>
92</ul></div>
93          </td>
94<td align="left">
95            <div class="itemizedlist"><ul type="disc">
96<li><p><span class="emphasis"><em>Any compiler supporting the preferred syntax</em></span></p></li>
97<li><p>Microsoft Visual C++ 6.0, 7.0</p></li>
98<li><p>Borland C++ 5.5.1</p></li>
99<li><p>Sun WorkShop 6 update 2 C++ 5.3</p></li>
100<li><p>Metrowerks CodeWarrior 8.1</p></li>
101</ul></div>
102          </td>
103</tr></tbody>
104</table></div>
105</div>
106<div class="section" lang="en">
107<div class="titlepage"><div><div><h3 class="title">
108<a name="id1626102"></a>Hello, World! (Beginner)</h3></div></div></div>
109<p>The following example writes "Hello, World!" using signals and
110slots. First, we create a signal <code class="computeroutput">sig</code>, a signal that
111takes no arguments and has a void return value. Next, we connect
112the <code class="computeroutput">hello</code> function object to the signal using the
113<code class="computeroutput">connect</code> method. Finally, use the signal
114<code class="computeroutput">sig</code> like a function to call the slots, which in turns
115invokes <code class="computeroutput">HelloWorld::operator()</code> to print "Hello,
116World!".</p>
117<div class="informaltable"><table class="table">
118<colgroup>
119<col>
120<col>
121</colgroup>
122<thead><tr>
123<th align="left">Preferred syntax</th>
124<th align="left">Portable syntax</th>
125</tr></thead>
126<tbody><tr>
127<td align="left">
128<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
129struct HelloWorld
130{
131  void operator()() const
132  {
133    std::cout &lt;&lt; "Hello, World!" &lt;&lt; std::endl;
134  }
135};
136
137// ...
138
139// Signal with no arguments and a void return value
140<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code>&lt;void ()&gt; sig;
141
142// Connect a HelloWorld slot
143HelloWorld hello;
144sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(hello);
145
146// Call all of the slots
147sig();
148</pre>
149</td>
150<td align="left">
151<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
152struct HelloWorld
153{
154  void operator()() const
155  {
156    std::cout &lt;&lt; "Hello, World!" &lt;&lt; std::endl;
157  }
158};
159
160// ...
161
162// Signal with no arguments and a void return value
163<code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal0</a></code>&lt;void&gt; sig;
164
165// Connect a HelloWorld slot
166HelloWorld hello;
167sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(hello);
168
169// Call all of the slots
170sig();
171</pre>
172</td>
173</tr></tbody>
174</table></div>
175</div>
176<div class="section" lang="en">
177<div class="titlepage"><div><div><h3 class="title">
178<a name="id1626257"></a>Calling multiple slots</h3></div></div></div>
179<div class="toc"><dl>
180<dt><span class="section"><a href="tutorial.html#id1626262">Connecting multiple slots (Beginner)</a></span></dt>
181<dt><span class="section"><a href="tutorial.html#id1626447">Ordering slot call groups (Intermediate)</a></span></dt>
182</dl></div>
183<div class="section" lang="en">
184<div class="titlepage"><div><div><h4 class="title">
185<a name="id1626262"></a>Connecting multiple slots (Beginner)</h4></div></div></div>
186<p>Calling a single slot from a signal isn't very interesting, so
187we can make the Hello, World program more interesting by splitting
188the work of printing "Hello, World!" into two completely separate
189slots. The first slot will print "Hello" and may look like
190this:</p>
191<pre class="programlisting">
192struct Hello
193{
194  void operator()() const
195  {
196    std::cout &lt;&lt; "Hello";
197  }
198};
199</pre>
200<p>The second slot will print ", World!" and a newline, to complete
201the program. The second slot may look like this:</p>
202<pre class="programlisting">
203struct World
204{
205  void operator()() const
206  {
207    std::cout &lt;&lt; ", World!" &lt;&lt; std::endl;
208  }
209};
210</pre>
211<p>Like in our previous example, we can create a signal
212<code class="computeroutput">sig</code> that takes no arguments and has a
213<code class="computeroutput">void</code> return value. This time, we connect both a
214<code class="computeroutput">hello</code> and a <code class="computeroutput">world</code> slot to the same
215signal, and when we call the signal both slots will be called.</p>
216<div class="informaltable"><table class="table">
217<colgroup>
218<col>
219<col>
220</colgroup>
221<thead><tr>
222<th align="left">Preferred syntax</th>
223<th align="left">Portable syntax</th>
224</tr></thead>
225<tbody><tr>
226<td align="left">
227<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
228<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code>&lt;void ()&gt; sig;
229
230sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(Hello());
231sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(World());
232
233sig();
234</pre>
235</td>
236<td align="left">
237<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
238<code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal0</a></code>&lt;void&gt; sig;
239
240sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(Hello());
241sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(World());
242
243sig();
244</pre>
245</td>
246</tr></tbody>
247</table></div>
248<p>By default, slots are called in first-in first-out (FIFO) order,
249so the output of this program will be as expected:</p>
250<pre class="programlisting">
251Hello, World!
252</pre>
253</div>
254<div class="section" lang="en">
255<div class="titlepage"><div><div><h4 class="title">
256<a name="id1626447"></a>Ordering slot call groups (Intermediate)</h4></div></div></div>
257<p>Slots are free to have side effects, and that can mean that some
258slots will have to be called before others even if they are not connected in that order. The Boost.Signals
259library allows slots to be placed into groups that are ordered in
260some way. For our Hello, World program, we want "Hello" to be
261printed before ", World!", so we put "Hello" into a group that must
262be executed before the group that ", World!" is in. To do this, we
263can supply an extra parameter at the beginning of the
264<code class="computeroutput">connect</code> call that specifies the group. Group values
265are, by default, <code class="computeroutput">int</code>s, and are ordered by the integer
266&lt; relation. Here's how we construct Hello, World:</p>
267<div class="informaltable"><table class="table">
268<colgroup>
269<col>
270<col>
271</colgroup>
272<thead><tr>
273<th align="left">Preferred syntax</th>
274<th align="left">Portable syntax</th>
275</tr></thead>
276<tbody><tr>
277<td align="left">
278<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
279<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code>&lt;void ()&gt; sig;
280sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(1, World());
281sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(0, Hello());
282sig();
283</pre>
284</td>
285<td align="left">
286<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
287<code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal0</a></code>&lt;void&gt; sig;
288sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(1, World());
289sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(0, Hello());
290sig();
291</pre>
292</td>
293</tr></tbody>
294</table></div>
295<p>This program will correctly print "Hello, World!", because the
296<code class="computeroutput">Hello</code> object is in group 0, which precedes group 1 where
297the <code class="computeroutput">World</code> object resides. The group
298parameter is, in fact, optional. We omitted it in the first Hello,
299World example because it was unnecessary when all of the slots are
300independent. So what happens if we mix calls to connect that use the
301group parameter and those that don't? The "unnamed" slots (i.e., those
302that have been connected without specifying a group name) can be
303placed at the front or back of the slot list (by passing
304<code class="computeroutput">boost::signals::at_front</code> or <code class="computeroutput">boost::signals::at_back</code>
305as the last parameter to <code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>, respectively), and defaults to the end of the list. When
306a group is specified, the final parameter describes where the slot
307will be placed within the group ordering. If we add a new slot
308to our example like this:</p>
309<pre class="programlisting">
310struct GoodMorning
311{
312  void operator()() const
313  {
314    std::cout &lt;&lt; "... and good morning!" &lt;&lt; std::endl;
315  }
316};
317
318sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(GoodMorning());
319</pre>
320<p>... we will get the result we wanted:</p>
321<pre class="programlisting">
322Hello, World!
323... and good morning!
324</pre>
325</div>
326</div>
327<div class="section" lang="en">
328<div class="titlepage"><div><div><h3 class="title">
329<a name="id1626670"></a>Passing values to and from slots</h3></div></div></div>
330<div class="toc"><dl>
331<dt><span class="section"><a href="tutorial.html#id1626676">Slot Arguments (Beginner)</a></span></dt>
332<dt><span class="section"><a href="tutorial.html#id1626921">Signal Return Values (Advanced)</a></span></dt>
333</dl></div>
334<div class="section" lang="en">
335<div class="titlepage"><div><div><h4 class="title">
336<a name="id1626676"></a>Slot Arguments (Beginner)</h4></div></div></div>
337<p>Signals can propagate arguments to each of the slots they call.
338For instance, a signal that propagates mouse motion events might
339want to pass along the new mouse coordinates and whether the mouse
340buttons are pressed.</p>
341<p>As an example, we'll create a signal that passes two
342<code class="computeroutput">float</code> arguments to its slots. Then we'll create a few
343slots that print the results of various arithmetic operations on
344these values.</p>
345<pre class="programlisting">
346void print_sum(float x, float y)
347{
348  std::cout &lt;&lt; "The sum is " &lt;&lt; x+y &lt;&lt; std::endl;
349}
350
351void print_product(float x, float y)
352{
353  std::cout &lt;&lt; "The product is " &lt;&lt; x*y &lt;&lt; std::endl;
354}
355
356void print_difference(float x, float y)
357{
358  std::cout &lt;&lt; "The difference is " &lt;&lt; x-y &lt;&lt; std::endl;
359}
360
361void print_quotient(float x, float y)
362{
363  std::cout &lt;&lt; "The quotient is " &lt;&lt; x/y &lt;&lt; std::endl;
364}
365</pre>
366<div class="informaltable"><table class="table">
367<colgroup>
368<col>
369<col>
370</colgroup>
371<thead><tr>
372<th align="left">Preferred syntax</th>
373<th align="left">Portable syntax</th>
374</tr></thead>
375<tbody><tr>
376<td align="left">
377<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
378<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code>&lt;void (float, float)&gt; sig;
379
380sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_sum);
381sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_product);
382sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_difference);
383sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_quotient);
384
385sig(5, 3);
386</pre>
387</td>
388<td align="left">
389<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
390<code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal2</a></code>&lt;void, float, float&gt; sig;
391
392sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_sum);
393sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_product);
394sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_difference);
395sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;print_quotient);
396
397sig(5, 3);
398</pre>
399</td>
400</tr></tbody>
401</table></div>
402<p>This program will print out the following:</p>
403<pre class="programlisting">
404The sum is 8
405The product is 15
406The difference is 2
407The quotient is 1.66667
408</pre>
409<p>So any values that are given to <code class="computeroutput">sig</code> when it is
410called like a function are passed to each of the slots. We have to
411declare the types of these values up front when we create the
412signal. The type <code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a>&lt;void (float,
413float)&gt;</code> means that the signal has a <code class="computeroutput">void</code>
414return value and takes two <code class="computeroutput">float</code> values. Any slot
415connected to <code class="computeroutput">sig</code> must therefore be able to take two
416<code class="computeroutput">float</code> values.</p>
417</div>
418<div class="section" lang="en">
419<div class="titlepage"><div><div><h4 class="title">
420<a name="id1626921"></a>Signal Return Values (Advanced)</h4></div></div></div>
421<p>Just as slots can receive arguments, they can also return
422values. These values can then be returned back to the caller of the
423signal through a <em class="firstterm">combiner</em>. The combiner is a mechanism
424that can take the results of calling slots (there many be no
425results or a hundred; we don't know until the program runs) and
426coalesces them into a single result to be returned to the caller.
427The single result is often a simple function of the results of the
428slot calls: the result of the last slot call, the maximum value
429returned by any slot, or a container of all of the results are some
430possibilities.</p>
431<p>We can modify our previous arithmetic operations example
432slightly so that the slots all return the results of computing the
433product, quotient, sum, or difference. Then the signal itself can
434return a value based on these results to be printed:</p>
435<div class="informaltable"><table class="table">
436<colgroup>
437<col>
438<col>
439</colgroup>
440<thead><tr>
441<th align="left">Preferred syntax</th>
442<th align="left">Portable syntax</th>
443</tr></thead>
444<tbody><tr>
445<td align="left">
446<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
447float product(float x, float y) { return x*y; }
448float quotient(float x, float y) { return x/y; }
449float sum(float x, float y) { return x+y; }
450float difference(float x, float y) { return x-y; }
451
452<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code>&lt;float (float x, float y)&gt; sig;
453
454sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;product);
455sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;quotient);
456sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;sum);
457sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;difference);
458
459std::cout &lt;&lt; sig(5, 3) &lt;&lt; std::endl;
460</pre>
461</td>
462<td align="left">
463<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
464float product(float x, float y) { return x*y; }
465float quotient(float x, float y) { return x/y; }
466float sum(float x, float y) { return x+y; }
467float difference(float x, float y) { return x-y; }
468
469<code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal2</a></code>&lt;float, float, float&gt; sig;
470
471sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;product);
472sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;quotient);
473sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;sum);
474sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;difference);
475
476std::cout &lt;&lt; sig(5, 3) &lt;&lt; std::endl;
477</pre>
478</td>
479</tr></tbody>
480</table></div>
481<p>This example program will output <code class="computeroutput">2</code>. This is because the
482default behavior of a signal that has a return type
483(<code class="computeroutput">float</code>, the first template argument given to the
484<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code> class template) is to call all slots and
485then return the result returned by the last slot called. This
486behavior is admittedly silly for this example, because slots have
487no side effects and the result is the last slot connect.</p>
488<p>A more interesting signal result would be the maximum of the
489values returned by any slot. To do this, we create a custom
490combiner that looks like this:</p>
491<pre class="programlisting">
492template&lt;typename T&gt;
493struct maximum
494{
495  typedef T result_type;
496
497  template&lt;typename InputIterator&gt;
498  T operator()(InputIterator first, InputIterator last) const
499  {
500    // If there are no slots to call, just return the
501    // default-constructed value
502    if (first == last)
503      return T();
504
505    T max_value = *first++;
506    while (first != last) {
507      if (max_value &lt; *first)
508        max_value = *first;
509      ++first;
510    }
511 
512    return max_value;
513  }
514};
515</pre>
516<p>The <code class="computeroutput">maximum</code> class template acts as a function
517object. Its result type is given by its template parameter, and
518this is the type it expects to be computing the maximum based on
519(e.g., <code class="computeroutput">maximum&lt;float&gt;</code> would find the maximum
520<code class="computeroutput">float</code> in a sequence of <code class="computeroutput">float</code>s). When a
521<code class="computeroutput">maximum</code> object is invoked, it is given an input
522iterator sequence <code class="computeroutput">[first, last)</code> that includes the
523results of calling all of the slots. <code class="computeroutput">maximum</code> uses this
524input iterator sequence to calculate the maximum element, and
525returns that maximum value.</p>
526<p>We actually use this new function object type by installing it
527as a combiner for our signal. The combiner template argument
528follows the signal's calling signature:</p>
529<div class="informaltable"><table class="table">
530<colgroup>
531<col>
532<col>
533</colgroup>
534<thead><tr>
535<th align="left">Preferred syntax</th>
536<th align="left">Portable syntax</th>
537</tr></thead>
538<tbody><tr>
539<td align="left">
540<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
541<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code>&lt;float (float x, float y),
542              maximum&lt;float&gt; &gt; sig;
543</pre>
544</td>
545<td align="left">
546<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
547<code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal2</a></code>&lt;float, float, float,
548               maximum&lt;float&gt; &gt; sig;
549</pre>
550</td>
551</tr></tbody>
552</table></div>
553<p>Now we can connect slots that perform arithmetic functions and
554use the signal:</p>
555<pre class="programlisting">
556sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;quotient);
557sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;product);
558sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;sum);
559sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;difference);
560
561std::cout &lt;&lt; sig(5, 3) &lt;&lt; std::endl;
562</pre>
563<p>The output of this program will be <code class="computeroutput">15</code>, because
564regardless of the order in which the slots are connected, the product
565of 5 and 3 will be larger than the quotient, sum, or
566difference.</p>
567<p>In other cases we might want to return all of the values
568computed by the slots together, in one large data structure. This
569is easily done with a different combiner:</p>
570<pre class="programlisting">
571template&lt;typename Container&gt;
572struct aggregate_values
573{
574  typedef Container result_type;
575
576  template&lt;typename InputIterator&gt;
577  Container operator()(InputIterator first, InputIterator last) const
578  {
579    return Container(first, last);
580  }
581};
582</pre>
583<p>
584Again, we can create a signal with this new combiner:
585</p>
586<div class="informaltable"><table class="table">
587<colgroup>
588<col>
589<col>
590</colgroup>
591<thead><tr>
592<th align="left">Preferred syntax</th>
593<th align="left">Portable syntax</th>
594</tr></thead>
595<tbody><tr>
596<td align="left">
597<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
598<code class="computeroutput"><a href="../boost/signal.html" title="Class template signal">boost::signal</a></code>&lt;float (float, float),
599    aggregate_values&lt;std::vector&lt;float&gt; &gt; &gt; sig;
600
601sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;quotient);
602sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;product);
603sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;sum);
604sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;difference);
605
606std::vector&lt;float&gt; results = sig(5, 3);
607std::copy(results.begin(), results.end(),
608    std::ostream_iterator&lt;float&gt;(cout, " "));
609</pre>
610</td>
611<td align="left">
612<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
613<code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal2</a></code>&lt;float, float, float,
614    aggregate_values&lt;std::vector&lt;float&gt; &gt; &gt; sig;
615
616sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;quotient);
617sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;product);
618sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;sum);
619sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(&amp;difference);
620
621std::vector&lt;float&gt; results = sig(5, 3);
622std::copy(results.begin(), results.end(),
623    std::ostream_iterator&lt;float&gt;(cout, " "));
624</pre>
625</td>
626</tr></tbody>
627</table></div>
628<p>The output of this program will contain 15, 8, 1.6667, and 2. It
629is interesting here that
630the first template argument for the <code class="computeroutput">signal</code> class,
631<code class="computeroutput">float</code>, is not actually the return type of the signal.
632Instead, it is the return type used by the connected slots and will
633also be the <code class="computeroutput">value_type</code> of the input iterators passed
634to the combiner. The combiner itself is a function object and its
635<code class="computeroutput">result_type</code> member type becomes the return type of the
636signal.</p>
637<p>The input iterators passed to the combiner transform dereference
638operations into slot calls. Combiners therefore have the option to
639invoke only some slots until some particular criterion is met. For
640instance, in a distributed computing system, the combiner may ask
641each remote system whether it will handle the request. Only one
642remote system needs to handle a particular request, so after a
643remote system accepts the work we do not want to ask any other
644remote systems to perform the same task. Such a combiner need only
645check the value returned when dereferencing the iterator, and
646return when the value is acceptable. The following combiner returns
647the first non-NULL pointer to a <code class="computeroutput">FulfilledRequest</code> data
648structure, without asking any later slots to fulfill the
649request:</p>
650<pre class="programlisting">
651struct DistributeRequest {
652  typedef FulfilledRequest* result_type;
653
654  template&lt;typename InputIterator&gt;
655  result_type operator()(InputIterator first, InputIterator last) const
656  {
657    while (first != last) {
658      if (result_type fulfilled = *first)
659        return fulfilled;
660      ++first;
661    }
662    return 0;
663  }
664};
665</pre>
666</div>
667</div>
668<div class="section" lang="en">
669<div class="titlepage"><div><div><h3 class="title">
670<a name="id1627585"></a>Connection Management</h3></div></div></div>
671<div class="toc"><dl>
672<dt><span class="section"><a href="tutorial.html#id1627590">Disconnecting Slots (Beginner)</a></span></dt>
673<dt><span class="section"><a href="tutorial.html#id1627712">Blocking Slots (Beginner)</a></span></dt>
674<dt><span class="section"><a href="tutorial.html#id1627791">Scoped connections (Intermediate)</a></span></dt>
675<dt><span class="section"><a href="tutorial.html#id1627841">Disconnecting equivalent slots (Intermediate)</a></span></dt>
676<dt><span class="section"><a href="tutorial.html#id1627926">Automatic connection management (Intermediate)</a></span></dt>
677<dt><span class="section"><a href="tutorial.html#id1628129">When can disconnections occur? (Intermediate)</a></span></dt>
678<dt><span class="section"><a href="tutorial.html#id1628199">Passing slots (Intermediate)</a></span></dt>
679</dl></div>
680<div class="section" lang="en">
681<div class="titlepage"><div><div><h4 class="title">
682<a name="id1627590"></a>Disconnecting Slots (Beginner)</h4></div></div></div>
683<p>Slots aren't expected to exist indefinately after they are
684connected. Often slots are only used to receive a few events and
685are then disconnected, and the programmer needs control to decide
686when a slot should no longer be connected.</p>
687<p>The entry point for managing connections explicitly is the
688<code class="computeroutput"><a href="../boost/signals/connection.html" title="Class connection">boost::signals::connection</a></code> class. The
689<code class="computeroutput"><a href="../boost/signals/connection.html" title="Class connection">connection</a></code> class uniquely represents the connection
690between a particular signal and a particular slot. The
691<code class="computeroutput"><a href="../boost/signals/connection.html#id1241414-bb">connected</a>()</code> method checks if the signal and slot are
692still connected, and the <code class="computeroutput"><a href="../boost/signals/connection.html#id1241377-bb">disconnect()</a></code> method
693disconnects the signal and slot if they are connected before it is
694called. Each call to the signal's <code class="computeroutput">connect()</code> method
695returns a connection object, which can be used to determine if the
696connection still exists or to disconnect the signal and slot.</p>
697<pre class="programlisting">
698boost::signals::connection c = sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(HelloWorld());
699if (c.<code class="computeroutput">connected</code>()) {
700<span class="emphasis"><em>// c is still connected to the signal</em></span>
701  sig(); <span class="emphasis"><em>// Prints "Hello, World!"</em></span>
702}
703
704c.disconnect(); <span class="emphasis"><em>// Disconnect the HelloWorld object</em></span>
705assert(!c.<code class="computeroutput">connected</code>()); <span class="emphasis"><em>c isn't connected any more</em></span>
706
707sig(); <span class="emphasis"><em>// Does nothing: there are no connected slots</em></span>
708</pre>
709</div>
710<div class="section" lang="en">
711<div class="titlepage"><div><div><h4 class="title">
712<a name="id1627712"></a>Blocking Slots (Beginner)</h4></div></div></div>
713<p>Slots can be temporarily "blocked", meaning that they will be
714ignored when the signal is invoked but have not been disconnected. The
715<code class="computeroutput">block</code> member function
716temporarily blocks a slot, which can be unblocked via
717<code class="computeroutput">unblock</code>. Here is an example of
718blocking/unblocking slots:</p>
719<pre class="programlisting">
720boost::signals::connection c = sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(HelloWorld());
721sig(); <span class="emphasis"><em>// Prints "Hello, World!"</em></span>
722
723c.<code class="computeroutput">block</code>(); <span class="emphasis"><em>// block the slot</em></span>
724assert(c.<code class="computeroutput">blocked</code>());
725sig(); <span class="emphasis"><em>// No output: the slot is blocked</em></span>
726
727c.<code class="computeroutput">unblock</code>(); <span class="emphasis"><em>// unblock the slot</em></span>
728sig(); <span class="emphasis"><em>// Prints "Hello, World!"</em></span>
729</pre>
730</div>
731<div class="section" lang="en">
732<div class="titlepage"><div><div><h4 class="title">
733<a name="id1627791"></a>Scoped connections (Intermediate)</h4></div></div></div>
734<p>The <code class="computeroutput">boost::signals::scoped_connection</code> class
735references a signal/slot connection that will be disconnected when
736the <code class="computeroutput">scoped_connection</code> class goes out of scope. This
737ability is useful when a connection need only be temporary,
738e.g.,</p>
739<pre class="programlisting">
740{
741  boost::signals::scoped_connection c = sig.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(ShortLived());
742  sig(); <span class="emphasis"><em>// will call ShortLived function object</em></span>
743}
744sig(); <span class="emphasis"><em>// ShortLived function object no longer connected to sig</em></span>
745</pre>
746</div>
747<div class="section" lang="en">
748<div class="titlepage"><div><div><h4 class="title">
749<a name="id1627841"></a>Disconnecting equivalent slots (Intermediate)</h4></div></div></div>
750<p>One can disconnect slots that are equivalent to a given function
751object using a form of the
752<code class="computeroutput"><a href="../boost/signalN.html#id896205-bb">disconnect</a></code> method, so long as
753the type of the function object has an accessible <code class="computeroutput">==</code>
754operator. For instance:
755
756</p>
757<div class="informaltable"><table class="table">
758<colgroup>
759<col>
760<col>
761</colgroup>
762<thead><tr>
763<th align="left">Preferred syntax</th>
764<th align="left">Portable syntax</th>
765</tr></thead>
766<tbody><tr>
767<td align="left">
768<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
769void foo();
770void bar();
771
772signal&lt;void()&gt; sig;
773
774sig.connect(&amp;foo);
775sig.connect(&amp;bar);
776
777// disconnects foo, but not bar
778sig.disconnect(&amp;foo);
779</pre>
780</td>
781<td align="left">
782<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
783void foo();
784void bar();
785
786signal0&lt;void&gt; sig;
787
788sig.connect(&amp;foo);
789sig.connect(&amp;bar);
790
791// disconnects foo, but not bar
792sig.disconnect(&amp;foo);
793</pre>
794</td>
795</tr></tbody>
796</table></div>
797</div>
798<div class="section" lang="en">
799<div class="titlepage"><div><div><h4 class="title">
800<a name="id1627926"></a>Automatic connection management (Intermediate)</h4></div></div></div>
801<p>Boost.Signals can automatically track the lifetime of objects
802involved in signal/slot connections, including automatic
803disconnection of slots when objects involved in the slot call are
804destroyed. For instance, consider a simple news delivery service,
805where clients connect to a news provider that then sends news to
806all connected clients as information arrives. The news delivery
807service may be constructed like this: </p>
808<div class="informaltable"><table class="table">
809<colgroup>
810<col>
811<col>
812</colgroup>
813<thead><tr>
814<th align="left">Preferred syntax</th>
815<th align="left">Portable syntax</th>
816</tr></thead>
817<tbody><tr>
818<td align="left">
819<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
820class NewsItem { /* ... */ };
821
822boost::signal&lt;void (const NewsItem&amp;)&gt; deliverNews;
823</pre>
824</td>
825<td align="left">
826<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
827class NewsItem { /* ... */ };
828
829boost::signal1&lt;void, const NewsItem&amp;&gt; deliverNews;
830</pre>
831</td>
832</tr></tbody>
833</table></div>
834<p>Clients that wish to receive news updates need only connect a
835function object that can receive news items to the
836<code class="computeroutput">deliverNews</code> signal. For instance, we may have a
837special message area in our application specifically for news,
838e.g.,:</p>
839<pre class="programlisting">
840struct NewsMessageArea : public MessageArea
841{
842public:
843  // ...
844
845  void displayNews(const NewsItem&amp; news) const
846  {
847    messageText = news.text();
848    update();
849  }
850};
851
852// ...
853NewsMessageArea newsMessageArea = new NewsMessageArea(/* ... */);
854// ...
855deliverNews.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(boost::bind(&amp;NewsMessageArea::displayNews,
856                                newsMessageArea, _1));
857</pre>
858<p>However, what if the user closes the news message area,
859destroying the <code class="computeroutput">newsMessageArea</code> object that
860<code class="computeroutput">deliverNews</code> knows about? Most likely, a segmentation
861fault will occur. However, with Boost.Signals one need only make
862<code class="computeroutput">NewsMessageArea</code> <span class="emphasis"><em>trackable</em></span>, and the slot
863involving <code class="computeroutput">newsMessageArea</code> will be disconnected when
864<code class="computeroutput">newsMessageArea</code> is destroyed. The
865<code class="computeroutput">NewsMessageArea</code> class is made trackable by deriving
866publicly from the <code class="computeroutput">boost::signals::trackable</code> class,
867e.g.:</p>
868<pre class="programlisting">
869struct NewsMessageArea : public MessageArea, public boost::signals::trackable
870{
871  // ...
872};
873</pre>
874<p>At this time there is a significant limitation to the use of
875<code class="computeroutput">trackable</code> objects in making slot connections: function
876objects built using Boost.Bind are understood, such that pointers
877or references to <code class="computeroutput">trackable</code> objects passed to
878<code class="computeroutput">boost::bind</code> will be found and tracked.</p>
879<p><span class="bold"><strong>Warning</strong></span>: User-defined function objects and function
880objects from other libraries (e.g., Boost.Function or Boost.Lambda)
881do not implement the required interfaces for <code class="computeroutput">trackable</code>
882object detection, and <span class="emphasis"><em>will silently ignore any bound trackable
883objects</em></span>. Future versions of the Boost libraries will address
884this limitation.</p>
885</div>
886<div class="section" lang="en">
887<div class="titlepage"><div><div><h4 class="title">
888<a name="id1628129"></a>When can disconnections occur? (Intermediate)</h4></div></div></div>
889<p>Signal/slot disconnections occur when any of these conditions
890occur:</p>
891<div class="itemizedlist"><ul type="disc">
892<li><p>The connection is explicitly disconnected via the connection's
893<code class="computeroutput">disconnect</code> method directly, or indirectly via the
894signal's <code class="computeroutput">disconnect</code> method or
895<code class="computeroutput">scoped_connection</code>'s destructor.</p></li>
896<li><p>A <code class="computeroutput">trackable</code> object bound to the slot is
897destroyed.</p></li>
898<li><p>The signal is destroyed.</p></li>
899</ul></div>
900<p>These events can occur at any time without disrupting a signal's
901calling sequence. If a signal/slot connection is disconnected at
902any time during a signal's calling sequence, the calling sequence
903will still continue but will not invoke the disconnected slot.
904Additionally, a signal may be destroyed while it is in a calling
905sequence, and which case it will complete its slot call sequence
906but may not be accessed directly.</p>
907<p>Signals may be invoked recursively (e.g., a signal A calls a
908slot B that invokes signal A...). The disconnection behavior does
909not change in the recursive case, except that the slot calling
910sequence includes slot calls for all nested invocations of the
911signal.</p>
912</div>
913<div class="section" lang="en">
914<div class="titlepage"><div><div><h4 class="title">
915<a name="id1628199"></a>Passing slots (Intermediate)</h4></div></div></div>
916<p>Slots in the Boost.Signals library are created from arbitrary
917function objects, and therefore have no fixed type. However, it is
918commonplace to require that slots be passed through interfaces that
919cannot be templates. Slots can be passed via the
920<code class="computeroutput">slot_type</code> for each particular signal type and any
921function object compatible with the signature of the signal can be
922passed to a <code class="computeroutput">slot_type</code> parameter. For instance:</p>
923<div class="informaltable"><table class="table">
924<colgroup>
925<col>
926<col>
927</colgroup>
928<thead><tr>
929<th align="left">Preferred syntax</th>
930<th align="left">Portable syntax</th>
931</tr></thead>
932<tbody><tr>
933<td align="left">
934<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
935class Button
936{
937  typedef boost::signal&lt;void (int x, int y)&gt; OnClick;
938
939public:
940  void doOnClick(const OnClick::slot_type&amp; slot);
941
942private:
943  OnClick onClick;
944};
945
946void Button::doOnClick(
947      const OnClick::slot_type&amp; slot
948    )
949{
950  onClick.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(slot);
951}
952
953void printCoordinates(long x, long y)
954{
955  std::cout &lt;&lt; "(" &lt;&lt; x &lt;&lt; ", " &lt;&lt; y &lt;&lt; ")\n";
956}
957
958void f(Button&amp; button)
959{
960  button.doOnClick(&amp;printCoordinates);
961}
962</pre>
963</td>
964<td align="left">
965<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting">
966class Button
967{
968  typedef <code class="computeroutput"><a href="../boost/signalN.html" title="Class template signalN">boost::signal2</a></code>&lt;void,int,int&gt; OnClick;
969
970public:
971  void doOnClick(const OnClick::slot_type&amp; slot);
972
973private:
974  OnClick onClick;
975};
976
977void Button::doOnClick(
978      const OnClick::slot_type&amp; slot
979    )
980{
981  onClick.<code class="computeroutput"><a href="../boost/signalN.html#id652932-bb">connect</a></code>(slot);
982}
983
984void printCoordinates(long x, long y)
985{
986  std::cout &lt;&lt; "(" &lt;&lt; x &lt;&lt; ", " &lt;&lt; y &lt;&lt; ")\n";
987}
988
989void f(Button&amp; button)
990{
991  button.doOnClick(&amp;printCoordinates);
992}
993</pre>
994</td>
995</tr></tbody>
996</table></div>
997<p>The <code class="computeroutput">doOnClick</code> method is now functionally equivalent
998to the <code class="computeroutput">connect</code> method of the <code class="computeroutput">onClick</code>
999signal, but the details of the <code class="computeroutput">doOnClick</code> method can be
1000hidden in an implementation detail file.</p>
1001</div>
1002</div>
1003<div class="section" lang="en">
1004<div class="titlepage"><div><div><h3 class="title">
1005<a name="id1628358"></a>Example: Document-View</h3></div></div></div>
1006<p>Signals can be used to implement flexible Document-View
1007  architectures. The document will contain a signal to which each of
1008  the views can connect. The following <code class="computeroutput">Document</code> class
1009  defines a simple text document that supports mulitple views. Note
1010  that it stores a single signal to which all of the views will be
1011  connected.</p>
1012<pre class="programlisting">class Document
1013{
1014public:
1015    typedef boost::signal&lt;void (bool)&gt;  signal_t;
1016    typedef boost::signals::connection  connection_t;
1017
1018public:
1019    Document()
1020    {}
1021
1022    connection_t connect(signal_t::slot_function_type subscriber)
1023    {
1024        return m_sig.connect(subscriber);
1025    }
1026
1027    void disconnect(connection_t subscriber)
1028    {
1029        subscriber.disconnect();
1030    }
1031
1032    void append(const char* s)
1033    {
1034        m_text += s;
1035        m_sig(true);
1036    }
1037
1038    const std::string&amp; getText() const
1039    {
1040        return m_text;
1041    }
1042
1043private:
1044    signal_t    m_sig;
1045    std::string m_text;
1046};</pre>
1047<p>Next, we can define a <code class="computeroutput">View</code> base class from which
1048  views can derive. This isn't strictly required, but it keeps the
1049  Document-View logic separate from the logic itself. Note that the
1050  constructor just connects the view to the document and the
1051  destructor disconnects the view.</p>
1052<pre class="programlisting">
1053class View
1054{
1055public:
1056    View(Document&amp; m)
1057        : m_document(m)
1058    {
1059        m_connection = m_document.connect(boost::bind(&amp;View::refresh, this, _1));
1060    }
1061
1062    virtual ~View()
1063    {
1064        m_document.disconnect(m_connection);
1065    }
1066
1067    virtual void refresh(bool bExtended) const = 0;
1068
1069protected:
1070    Document&amp;               m_document;
1071
1072private:
1073    Document::connection_t  m_connection;
1074};
1075  </pre>
1076<p>Finally, we can begin to define views. The
1077  following <code class="computeroutput">TextView</code> class provides a simple view of the
1078    document text.</p>
1079<pre class="programlisting">class TextView : public View
1080{
1081public:
1082    TextView(Document&amp; doc)
1083        : View(doc)
1084    {}
1085
1086    virtual void refresh(bool bExtended) const
1087    {
1088        std::cout &lt;&lt; "TextView: " &lt;&lt; m_document.getText() &lt;&lt; std::endl;
1089    }
1090};</pre>
1091<p>Alternatively, we can provide a view of the document
1092    translated into hex values using the <code class="computeroutput">HexView</code>
1093    view:</p>
1094<pre class="programlisting">class HexView : public View
1095{
1096public:
1097    HexView(Document&amp; doc)
1098        : View(doc)
1099    {}
1100
1101    virtual void refresh(bool bExtended) const
1102    {
1103        const std::string&amp;  s = m_document.getText();
1104
1105        std::cout &lt;&lt; "HexView:";
1106
1107        for (std::string::const_iterator it = s.begin(); it != s.end(); ++it)
1108            std::cout &lt;&lt; ' ' &lt;&lt; std::hex &lt;&lt; static_cast&lt;int&gt;(*it);
1109
1110        std::cout &lt;&lt; std::endl;
1111    }
1112};</pre>
1113<p>To tie the example together, here is a
1114  simple <code class="computeroutput">main</code> function that sets up two views and then
1115    modifies the document:</p>
1116<pre class="programlisting">int main(int argc, char* argv[])
1117{
1118    Document    doc;
1119    TextView    v1(doc);
1120    HexView     v2(doc);
1121
1122    doc.append(argc == 2 ? argv[1] : "Hello world!");
1123    return 0;
1124}</pre>
1125<p>The complete example source, contributed by Keith MacDonald,
1126    is available in <a href="../../../libs/signals/example/doc_view.cpp" target="_top"><code class="computeroutput">libs/signals/example/doc_view.cpp</code></a>.</p>
1127</div>
1128<div class="section" lang="en">
1129<div class="titlepage"><div><div><h3 class="title">
1130<a name="id1628486"></a>Linking against the Signals library</h3></div></div></div>
1131<p>Part of the Boost.Signals library is compiled into a binary
1132  library that must be linked into your application to use
1133  Signals. Please refer to
1134    the <a href="../../../more/getting_started.html" target="_top">Getting Started</a>
1135  guide. You will need to link against the <code class="computeroutput">boost_signals</code>
1136  library.</p>
1137</div>
1138</div>
1139<table width="100%"><tr>
1140<td align="left"><small><p>Last revised: January 29, 2007 at 20:04:57 GMT</p></small></td>
1141<td align="right"><small>Copyright © 2001-2004 Douglas Gregor</small></td>
1142</tr></table>
1143<hr>
1144<div class="spirit-nav">
1145<a accesskey="p" href="../signals.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../signals.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../images/next.png" alt="Next"></a>
1146</div>
1147</body>
1148</html>
Note: See TracBrowser for help on using the repository browser.