• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4<title>Annex: Alternatives</title>
5<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7<link rel="home" href="../index.html" title="Chapter 1. Boost.LocalFunction 1.0.0">
8<link rel="up" href="../index.html" title="Chapter 1. Boost.LocalFunction 1.0.0">
9<link rel="prev" href="examples.html" title="Examples">
10<link rel="next" href="no_variadic_macros.html" title="Annex: No Variadic Macros">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="examples.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="no_variadic_macros.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h2 class="title" style="clear: both">
27<a name="boost_localfunction.alternatives"></a><a class="link" href="alternatives.html" title="Annex: Alternatives">Annex: Alternatives</a>
28</h2></div></div></div>
29<p>
30      This section compares the features offered by this library with similar features
31      offered by C++ and by other libraries.
32    </p>
33<h4>
34<a name="boost_localfunction.alternatives.h0"></a>
35      <span class="phrase"><a name="boost_localfunction.alternatives.features"></a></span><a class="link" href="alternatives.html#boost_localfunction.alternatives.features">Features</a>
36    </h4>
37<p>
38      The following table compares local function features.
39    </p>
40<div class="informaltable"><table class="table">
41<colgroup>
42<col>
43<col>
44<col>
45<col>
46<col>
47<col>
48</colgroup>
49<thead><tr>
50<th>
51              <p>
52                Local Function Feature
53              </p>
54            </th>
55<th>
56              <p>
57                Boost.LocalFunction
58              </p>
59            </th>
60<th>
61              <p>
62                C++11 Lambda Function (Not C++03)
63              </p>
64            </th>
65<th>
66              <p>
67                Local Functor
68              </p>
69            </th>
70<th>
71              <p>
72                Global Functor (Not Local)
73              </p>
74            </th>
75<th>
76              <p>
77                Boost.Phoenix
78              </p>
79            </th>
80</tr></thead>
81<tbody>
82<tr>
83<td>
84              <p>
85                <span class="emphasis"><em>Can be defined locally</em></span>
86              </p>
87            </td>
88<td>
89              <p>
90                Yes.
91              </p>
92            </td>
93<td>
94              <p>
95                Yes.
96              </p>
97            </td>
98<td>
99              <p>
100                Yes.
101              </p>
102            </td>
103<td>
104              <p>
105                No. Therefore this not really an alternative implementation of local
106                functions but it is listed here just for comparison.
107              </p>
108            </td>
109<td>
110              <p>
111                Yes.
112              </p>
113            </td>
114</tr>
115<tr>
116<td>
117              <p>
118                <span class="emphasis"><em>Can be defined using C++ statement syntax</em></span>
119              </p>
120            </td>
121<td>
122              <p>
123                Yes. Plus eventual compiler errors and debugging retain their usual
124                meaning and format.
125              </p>
126            </td>
127<td>
128              <p>
129                Yes. Plus eventual compiler errors and debugging retain their usual
130                meaning and format.
131              </p>
132            </td>
133<td>
134              <p>
135                Yes. Plus eventual compiler errors and debugging retain their usual
136                meaning and format.
137              </p>
138            </td>
139<td>
140              <p>
141                Yes. Plus eventual compiler errors and debugging retain their usual
142                meaning and format.
143              </p>
144            </td>
145<td>
146              <p>
147                No (it uses C++ <a href="http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template" target="_top">expression
148                template</a> syntax).
149              </p>
150            </td>
151</tr>
152<tr>
153<td>
154              <p>
155                <span class="emphasis"><em>Can be defined within expressions</em></span>
156              </p>
157            </td>
158<td>
159              <p>
160                No. It can be defined only within declarations.
161              </p>
162            </td>
163<td>
164              <p>
165                Yes (plus the local function can be unnamed).
166              </p>
167            </td>
168<td>
169              <p>
170                No. It can be defined only within declarations.
171              </p>
172            </td>
173<td>
174              <p>
175                No. It can be defined only within declarations.
176              </p>
177            </td>
178<td>
179              <p>
180                Yes (plus the local function can be unnamed).
181              </p>
182            </td>
183</tr>
184<tr>
185<td>
186              <p>
187                <span class="emphasis"><em>Can be passed as template parameter (e.g., to STL algorithms)</em></span>
188              </p>
189            </td>
190<td>
191              <p>
192                Yes. The <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
193                standard does not allow to pass local types as template parameters
194                (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>)
195                but this library implements a "trick" to get around this
196                limitation (see the <a class="link" href="implementation.html" title="Annex: Implementation">Implementation</a>
197                section).
198              </p>
199            </td>
200<td>
201              <p>
202                Yes.
203              </p>
204            </td>
205<td>
206              <p>
207                No on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
208                compilers (but yes on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
209                compilers and some compilers like MSVC 8.0, see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>).
210              </p>
211            </td>
212<td>
213              <p>
214                Yes.
215              </p>
216            </td>
217<td>
218              <p>
219                Yes.
220              </p>
221            </td>
222</tr>
223<tr>
224<td>
225              <p>
226                <span class="emphasis"><em>Access variables in scope</em></span>
227              </p>
228            </td>
229<td>
230              <p>
231                Yes. The variable names are repeated in the function declaration
232                so they can be bound by value, by constant value, by reference, and
233                by constant reference (the object <code class="computeroutput"><span class="keyword">this</span></code>
234                can also be bound using <code class="computeroutput"><span class="identifier">this_</span></code>).
235              </p>
236            </td>
237<td>
238              <p>
239                Yes. The variable names are repeated in the function declaration
240                (plus there is a short-hand syntax to bind all variables in scope
241                at once) so they can be bound by constant value and by reference
242                (the object <code class="computeroutput"><span class="keyword">this</span></code> can
243                also be bound). However, variables cannot be bound by constant references
244                (see below).
245              </p>
246            </td>
247<td>
248              <p>
249                No. Programmers must manually program functor data members and explicitly
250                specify their types to access variables in scope.
251              </p>
252            </td>
253<td>
254              <p>
255                No. Programmers must manually program functor data members and explicitly
256                specify their types to access variables in scope.
257              </p>
258            </td>
259<td>
260              <p>
261                Yes. Variables in scope are accessible as usual within expressions
262                (plus <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">let</span></code> can be used to bind variables
263                by constant reference).
264              </p>
265            </td>
266</tr>
267<tr>
268<td>
269              <p>
270                <span class="emphasis"><em><a href="http://en.wikipedia.org/wiki/Type_polymorphism#Parametric_polymorphism" target="_top">Polymorphic</a>
271                in the function parameter type</em></span>
272              </p>
273            </td>
274<td>
275              <p>
276                No (local functions cannot be function templates).
277              </p>
278            </td>
279<td>
280              <p>
281                No (<a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
282                lambdas cannot be function templates).
283              </p>
284            </td>
285<td>
286              <p>
287                No (local classes cannot have member function templates).
288              </p>
289            </td>
290<td>
291              <p>
292                Yes.
293              </p>
294            </td>
295<td>
296              <p>
297                Yes.
298              </p>
299            </td>
300</tr>
301</tbody>
302</table></div>
303<p>
304      <span class="bold"><strong>C++11 Lambda Function</strong></span>
305    </p>
306<p>
307      <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
308      lambda functions</a> have most of the features of this library plus some
309      additional feature (see also the example in the <a class="link" href="../index.html#boost_localfunction.introduction" title="Introduction">Introduction</a>
310      section):
311    </p>
312<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
313<li class="listitem">
314          <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
315          lambda functions</a> can be defined within expressions while this library
316          local functions can only be defined at declaration scope.
317        </li>
318<li class="listitem">
319          <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
320          lambda functions</a> are only supported by the <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
321          standard so they are not supported by all C++ compilers. This library local
322          functions can be programmed also on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
323          compilers (and they have performances comparable to <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
324          lambda functions</a> on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
325          compilers).
326        </li>
327<li class="listitem">
328          <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
329          lambda functions</a> do not allow to bind variables in scope by constant
330          reference. Because a variable cannot be bound by constant reference, <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
331          lambda functions</a> can bind a variable by constant only if the variable
332          is <code class="computeroutput"><span class="identifier">CopyConstructible</span></code> and
333          the binding requires a (potentially expensive) extra copy operation. Constant
334          reference binding is instead supported by this library.
335        </li>
336<li class="listitem">
337          <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
338          lambda functions</a> do not allow to bind data members selectively
339          without binding also the object <code class="computeroutput"><span class="keyword">this</span></code>
340          while this library local functions can bind either selected data members
341          or the entire object <code class="computeroutput"><span class="keyword">this</span></code>
342          (using <code class="computeroutput"><span class="identifier">this_</span></code>).
343        </li>
344<li class="listitem">
345          <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
346          lambda functions</a> provide a short-hand syntax to bind all variables
347          in scope at once (<code class="computeroutput"><span class="special">&amp;</span></code> or
348          <code class="computeroutput"><span class="special">=</span></code>) while this library local
349          function always require to bind variables naming them one-by-one.
350        </li>
351</ul></div>
352<p>
353      For example, for non-copyable objects (see also <a href="../../../example/noncopyable_cxx11_lambda_error.cpp" target="_top"><code class="literal">noncopyable_cxx11_lambda_error.cpp</code></a>
354      and <a href="../../../example/noncopyable_local_function.cpp" target="_top"><code class="literal">noncopyable_local_function.cpp</code></a>):
355    </p>
356<div class="informaltable"><table class="table">
357<colgroup>
358<col>
359<col>
360</colgroup>
361<thead><tr>
362<th>
363              <p>
364                C++11 Lambda Function
365              </p>
366            </th>
367<th>
368              <p>
369                Boost.LocalFunction
370              </p>
371            </th>
372</tr></thead>
373<tbody><tr>
374<td>
375              <p>
376</p>
377<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span><span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span> <span class="special">{</span>
378    <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
379    <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
380<span class="special">};</span>
381
382
383<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
384    <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
385
386    <span class="keyword">auto</span> <span class="identifier">f</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">x</span><span class="special">](</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>    <span class="comment">// Error: x is non-copyable, but if</span>
387        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>  <span class="comment">// bind `&amp;x` then `x` is not constant.</span>
388    <span class="special">};</span>
389    <span class="identifier">f</span><span class="special">();</span>
390
391    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
392<span class="special">}</span>
393</pre>
394<p>
395              </p>
396            </td>
397<td>
398              <p>
399</p>
400<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span><span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">noncopyable</span> <span class="special">{</span>
401    <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
402    <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
403<span class="special">};</span>
404<span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="comment">// Register for `bind&amp; x` below.</span>
405
406<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
407    <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
408
409    <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>  <span class="comment">// OK: No copy</span>
410        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>                      <span class="comment">// and constant.</span>
411    <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span>
412    <span class="identifier">f</span><span class="special">();</span>
413
414    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
415<span class="special">}</span>
416</pre>
417<p>
418              </p>
419            </td>
420</tr></tbody>
421</table></div>
422<p>
423      Or, for objects with expensive copy operations (see also <a href="../../../example/expensive_copy_cxx11_lambda.cpp" target="_top"><code class="literal">expensive_copy_cxx11_lambda.cpp</code></a>
424      and <a href="../../../example/expensive_copy_local_function.cpp" target="_top"><code class="literal">expensive_copy_local_function.cpp</code></a>):
425    </p>
426<div class="informaltable"><table class="table">
427<colgroup>
428<col>
429<col>
430</colgroup>
431<thead><tr>
432<th>
433              <p>
434                C++11 Lambda Function
435              </p>
436            </th>
437<th>
438              <p>
439                Boost.LocalFunction
440              </p>
441            </th>
442</tr></thead>
443<tbody><tr>
444<td>
445              <p>
446</p>
447<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span> <span class="special">{</span>
448    <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
449    <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
450    <span class="identifier">n</span><span class="special">(</span><span class="identifier">n</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Some time consuming copy operation.</span>
451        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">10000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</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="char">'.'</span><span class="special">;</span>
452    <span class="special">}</span>
453<span class="special">};</span>
454
455
456<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
457    <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
458
459    <span class="keyword">auto</span> <span class="identifier">f</span> <span class="special">=</span> <span class="special">[</span><span class="identifier">x</span><span class="special">]()</span> <span class="special">{</span>        <span class="comment">// Problem: Expensive copy, but if bind</span>
460        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>  <span class="comment">// by `&amp;x` then `x` is not constant.</span>
461    <span class="special">};</span>
462    <span class="identifier">f</span><span class="special">();</span>
463
464    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
465<span class="special">}</span>
466</pre>
467<p>
468              </p>
469            </td>
470<td>
471              <p>
472</p>
473<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">struct</span> <span class="identifier">n</span> <span class="special">{</span>
474    <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
475    <span class="identifier">n</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">_i</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">_i</span><span class="special">)</span> <span class="special">{}</span>
476    <span class="identifier">n</span><span class="special">(</span><span class="identifier">n</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">):</span> <span class="identifier">i</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Some time consuming copy operation.</span>
477        <span class="keyword">for</span> <span class="special">(</span><span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">10000</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</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="char">'.'</span><span class="special">;</span>
478    <span class="special">}</span>
479<span class="special">};</span>
480<span class="identifier">BOOST_TYPEOF_REGISTER_TYPE</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span> <span class="comment">// Register for `bind&amp; x` below.</span>
481
482<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
483    <span class="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span>
484
485    <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span>  <span class="comment">// OK: No copy expensive</span>
486        <span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">.</span><span class="identifier">i</span> <span class="special">==</span> <span class="special">-</span><span class="number">1</span><span class="special">);</span>                      <span class="comment">// copy but constant.</span>
487    <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span>
488    <span class="identifier">f</span><span class="special">();</span>
489
490    <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span>
491<span class="special">}</span>
492</pre>
493<p>
494              </p>
495            </td>
496</tr></tbody>
497</table></div>
498<p>
499      When constant binding functionality is needed for <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
500      lambda functions</a>, the best alternative might be to bind an extra local
501      variable declared constant and initialized to the original variable (for example,
502      see <span class="emphasis"><em>constant blocks</em></span> implemented with <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
503      lambda functions</a> in the <a class="link" href="examples.html" title="Examples">Examples</a>
504      section).
505    </p>
506<p>
507      <span class="bold"><strong>Local Functor</strong></span>
508    </p>
509<p>
510      The following example compares local functions with C++ local functors (see
511      also <a href="../../../example/add_local_functor.cpp" target="_top"><code class="literal">add_local_functor.cpp</code></a>
512      and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>):
513    </p>
514<div class="informaltable"><table class="table">
515<colgroup>
516<col>
517<col>
518</colgroup>
519<thead><tr>
520<th>
521              <p>
522                Local Functor
523              </p>
524            </th>
525<th>
526              <p>
527                Boost.LocalFunction
528              </p>
529            </th>
530</tr></thead>
531<tbody><tr>
532<td>
533              <p>
534</p>
535<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
536    <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
537
538    <span class="keyword">struct</span> <span class="identifier">local_add</span> <span class="special">{</span> <span class="comment">// Unfortunately, boilerplate code to program the class.</span>
539        <span class="identifier">local_add</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">_sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">_factor</span><span class="special">):</span> <span class="identifier">sum</span><span class="special">(</span><span class="identifier">_sum</span><span class="special">),</span> <span class="identifier">factor</span><span class="special">(</span><span class="identifier">_factor</span><span class="special">)</span> <span class="special">{}</span>
540
541        <span class="keyword">inline</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Body uses C++ statement syntax.</span>
542            <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
543        <span class="special">}</span>
544
545    <span class="keyword">private</span><span class="special">:</span> <span class="comment">// Unfortunately, cannot bind so repeat variable types.</span>
546        <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">;</span> <span class="comment">// Access `sum` by reference.</span>
547        <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">factor</span><span class="special">;</span> <span class="comment">// Make `factor` constant.</span>
548    <span class="special">}</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">sum</span><span class="special">,</span> <span class="identifier">factor</span><span class="special">);</span>
549
550    <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
551    <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
552    <span class="comment">// Unfortunately, cannot pass as template parameter to `std::for_each`.</span>
553    <span class="keyword">for</span><span class="special">(</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">2</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">nums</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span>
554
555    <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>
556    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
557<span class="special">}</span>
558</pre>
559<p>
560              </p>
561            </td>
562<td>
563              <p>
564</p>
565<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>                            <span class="comment">// Some local scope.</span>
566    <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>               <span class="comment">// Variables in scope to bind.</span>
567
568    <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span>
569        <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
570    <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
571
572    <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>                                 <span class="comment">// Call the local function.</span>
573    <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
574    <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span>     <span class="comment">// Pass it to an algorithm.</span>
575
576    <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>                  <span class="comment">// Assert final summation value.</span>
577    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
578<span class="special">}</span>
579</pre>
580<p>
581              </p>
582            </td>
583</tr></tbody>
584</table></div>
585<p>
586      <span class="bold"><strong>Global Functor</strong></span>
587    </p>
588<p>
589      The following example compares local functions with C++ global functors (see
590      also <a href="../../../example/add_global_functor.cpp" target="_top"><code class="literal">add_global_functor.cpp</code></a>
591      and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>):
592    </p>
593<div class="informaltable"><table class="table">
594<colgroup>
595<col>
596<col>
597</colgroup>
598<thead><tr>
599<th>
600              <p>
601                Global Functor
602              </p>
603            </th>
604<th>
605              <p>
606                Boost.LocalFunction
607              </p>
608            </th>
609</tr></thead>
610<tbody><tr>
611<td>
612              <p>
613</p>
614<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="comment">// Unfortunately, cannot be defined locally (so not a real alternative).</span>
615<span class="keyword">struct</span> <span class="identifier">global_add</span> <span class="special">{</span> <span class="comment">// Unfortunately, boilerplate code to program the class.</span>
616    <span class="identifier">global_add</span><span class="special">(</span><span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">_sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">_factor</span><span class="special">):</span> <span class="identifier">sum</span><span class="special">(</span><span class="identifier">_sum</span><span class="special">),</span> <span class="identifier">factor</span><span class="special">(</span><span class="identifier">_factor</span><span class="special">)</span> <span class="special">{}</span>
617
618    <span class="keyword">inline</span> <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Body uses C++ statement syntax.</span>
619        <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
620    <span class="special">}</span>
621
622<span class="keyword">private</span><span class="special">:</span> <span class="comment">// Unfortunately, cannot bind so repeat variable types.</span>
623    <span class="keyword">int</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">;</span> <span class="comment">// Access `sum` by reference.</span>
624    <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">factor</span><span class="special">;</span> <span class="comment">// Make `factor` constant.</span>
625<span class="special">};</span>
626
627<span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
628    <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
629
630    <span class="identifier">global_add</span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">sum</span><span class="special">,</span> <span class="identifier">factor</span><span class="special">);</span>
631
632    <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>
633    <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
634    <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span> <span class="comment">// Passed as template parameter.</span>
635
636    <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>
637    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
638<span class="special">}</span>
639</pre>
640<p>
641              </p>
642            </td>
643<td>
644              <p>
645</p>
646<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>                            <span class="comment">// Some local scope.</span>
647    <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>               <span class="comment">// Variables in scope to bind.</span>
648
649    <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span>
650        <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
651    <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
652
653    <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>                                 <span class="comment">// Call the local function.</span>
654    <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
655    <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span>     <span class="comment">// Pass it to an algorithm.</span>
656
657    <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>                  <span class="comment">// Assert final summation value.</span>
658    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
659<span class="special">}</span>
660</pre>
661<p>
662              </p>
663            </td>
664</tr></tbody>
665</table></div>
666<p>
667      However, note that global functors do not allow to define the function locally
668      so they are not a real alternative implementation of local functions.
669    </p>
670<p>
671      <span class="bold"><strong>Boost.Phoenix</strong></span>
672    </p>
673<p>
674      The following example compares local functions with <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>
675      (see also <a href="../../../example/add_phoenix.cpp" target="_top"><code class="literal">add_phoenix.cpp</code></a>
676      and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>):
677    </p>
678<div class="informaltable"><table class="table">
679<colgroup>
680<col>
681<col>
682</colgroup>
683<thead><tr>
684<th>
685              <p>
686                Boost.Phoenix
687              </p>
688            </th>
689<th>
690              <p>
691                Boost.LocalFunction
692              </p>
693            </th>
694</tr></thead>
695<tbody><tr>
696<td>
697              <p>
698</p>
699<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>
700    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">let</span><span class="special">;</span>
701    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">local_names</span><span class="special">::</span><span class="identifier">_f</span><span class="special">;</span>
702    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">cref</span><span class="special">;</span>
703    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">ref</span><span class="special">;</span>
704    <span class="keyword">using</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">arg_names</span><span class="special">::</span><span class="identifier">_1</span><span class="special">;</span>
705
706    <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>
707    <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
708
709    <span class="comment">// Passed to template, `factor` by constant, and defined in expression.</span>
710    <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">3</span><span class="special">,</span> <span class="identifier">let</span><span class="special">(</span><span class="identifier">_f</span> <span class="special">=</span> <span class="identifier">cref</span><span class="special">(</span><span class="identifier">factor</span><span class="special">))[</span>
711        <span class="comment">// Unfortunately, body cannot use C++ statement syntax.</span>
712        <span class="identifier">ref</span><span class="special">(</span><span class="identifier">sum</span><span class="special">)</span> <span class="special">+=</span> <span class="identifier">_f</span> <span class="special">*</span> <span class="identifier">_1</span><span class="special">,</span> <span class="identifier">_1</span> <span class="comment">// Access `sum` by reference.</span>
713    <span class="special">]);</span>
714
715    <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>
716    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
717<span class="special">}</span>
718</pre>
719<p>
720              </p>
721            </td>
722<td>
723              <p>
724</p>
725<pre xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="table-programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span>                            <span class="comment">// Some local scope.</span>
726    <span class="keyword">int</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">,</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span>               <span class="comment">// Variables in scope to bind.</span>
727
728    <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">factor</span><span class="special">,</span> <span class="identifier">bind</span><span class="special">&amp;</span> <span class="identifier">sum</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span>
729        <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span>
730    <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span>
731
732    <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span>                                 <span class="comment">// Call the local function.</span>
733    <span class="keyword">int</span> <span class="identifier">nums</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">};</span>
734    <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">nums</span><span class="special">,</span> <span class="identifier">nums</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">add</span><span class="special">);</span>     <span class="comment">// Pass it to an algorithm.</span>
735
736    <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">sum</span> <span class="special">==</span> <span class="number">60</span><span class="special">);</span>                  <span class="comment">// Assert final summation value.</span>
737    <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span>
738<span class="special">}</span>
739</pre>
740<p>
741              </p>
742            </td>
743</tr></tbody>
744</table></div>
745<p>
746      The comparison in this section does not include the <a href="http://www.boost.org/libs/lambda" target="_top">Boost.Lambda</a>
747      library because that library is obsolete and it was replaced by <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>.
748      The <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a> library
749      version 3.0 is used for this comparison.
750    </p>
751<h4>
752<a name="boost_localfunction.alternatives.h1"></a>
753      <span class="phrase"><a name="boost_localfunction.alternatives.performances"></a></span><a class="link" href="alternatives.html#boost_localfunction.alternatives.performances">Performances</a>
754    </h4>
755<p>
756      The following tables compare run-times, compile-times, and binary sizes for
757      the different alternatives to local functions presented in this section.
758    </p>
759<p>
760      Overall, this library has compile-times and generates binary sizes similar
761      to the ones of the other approaches. This library run-times on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
762      compilers were measured to be larger than other approaches when compiler optimization
763      is enabled (using <code class="computeroutput"><span class="identifier">bjam</span> <span class="identifier">release</span>
764      <span class="special">...</span></code>). However, on compilers that allow
765      to pass local types as template parameters (e.g., MSVC 8.0 or GCC 4.5.3 with
766      <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> features
767      enabled <code class="literal">-std=c++0x</code>, see also <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>
768      and <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>)
769      this library automatically generates optimized code that runs as fast as the
770      fastest of the other approaches (see the "Boost.LocalFunction" approach
771      below). When this library local function is specified <code class="computeroutput"><span class="keyword">inline</span></code>
772      (see the "Boost.LocalFunction Inline" approach below and the <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced Topics</a> section)
773      its run-times are always comparable to both the "Local Functor" and
774      "Global Functor" approaches. However, in these cases the local function
775      cannot be portably passed as template parameter (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>
776      and <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>)
777      so <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span></code> is replaced by a for-loop (on MSVC
778      the for-loop, and not the local function in fact the same applies to local
779      functors, was measured to have worst performances than using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span></code>).
780      Finally, this library run-times are always among the fastest when no compiler
781      optimization is enabled (using <code class="computeroutput"><span class="identifier">bjam</span>
782      <span class="identifier">debug</span> <span class="special">...</span></code>).
783    </p>
784<div class="note"><table border="0" summary="Note">
785<tr>
786<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td>
787<th align="left">Note</th>
788</tr>
789<tr><td align="left" valign="top"><p>
790        The run-time performances of this library local functions are explained because
791        on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
792        compliant compilers (e.g., GCC 4.5.3 without <code class="literal">-std=c++0x</code>)
793        this library needs to use a function pointer in order to portably pass the
794        local function class as a template parameter (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>
795        and the <a class="link" href="implementation.html" title="Annex: Implementation">Implementation</a>
796        section). For all tested compilers, this function pointer prevents the compiler
797        optimization algorithms from inlining the local function calls. Instead,
798        the functors used by other approaches (e.g., <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>)
799        have been observed to allow all tested compilers to inline all the function
800        calls for optimization. This run-time performance cost is not present on
801        compilers that allow to pass local types as template parameters (e.g., MSVC
802        8.0 or GCC 4.5.3 with <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
803        features enabled <code class="literal">-std=c++0x</code>, see <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s
804        <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>)
805        because this library does not have to use the extra function pointer to implement
806        the local function call (it directly passes the local class type as template
807        parameter).
808      </p></td></tr>
809</table></div>
810<p>
811      This run-time performance cost on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
812      compilers might or might not be an issue depending on the performance requirements
813      of specific applications. For example, an application might already be using
814      a number of indirect function calls (function pointers, virtual functions,
815      etc) for which the overhead added by using the one extra function pointer required
816      by the local function call might not be noticeable within the overall program
817      run-time.
818    </p>
819<p>
820      Finally, note that only a very simple local function body with just a single
821      instruction was used for the anaylsis presented here (see the source files
822      below). The authors have not studied how this library and the other approaches
823      will perform with respect to each other when a more complex set of instructions
824      is programmed for the local function body (e.g., <span class="emphasis"><em>if</em></span> a
825      more complex set of instructions in the local function body were to inhibit
826      some compiler from inlining function objects also other approaches like <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11
827      lambda functions</a> and <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>
828      <span class="emphasis"><em>could</em></span> start to show higher run-times even when optimization
829      is enabled).
830    </p>
831<p>
832      The following commands were executed from the library example directory to
833      measure compile-time, binary size, and run-time respectively:
834    </p>
835<pre class="programlisting">&gt; touch &lt;FILE_NAME&gt;.cpp                             # force recompilation
836&gt; python chrono.py bjam {release|debug} &lt;FILE_NAME&gt; # compile-time
837&gt; size &lt;FILE_NAME&gt;                                  # binary size
838&gt; ./&lt;FILE_NAME&gt;                                     # run-time
839</pre>
840<p>
841      The local function was called <code class="literal">1e8</code> times to add together
842      all the elements of a vector and the run-time was measured using <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Chrono</a>
843      averaging over <code class="literal">10</code> executions of the vector summation (see
844      the source files below).
845    </p>
846<div class="informaltable"><table class="table">
847<colgroup>
848<col>
849<col>
850<col>
851</colgroup>
852<thead><tr>
853<th>
854              <p>
855                Legend
856              </p>
857            </th>
858<th>
859              <p>
860                Approach
861              </p>
862            </th>
863<th>
864              <p>
865                Source File
866              </p>
867            </th>
868</tr></thead>
869<tbody>
870<tr>
871<td>
872              <p>
873                <span class="inlinemediaobject"><img src="../../../example/profile_legend_local_function.png" alt="profile_legend_local_function"></span>
874              </p>
875            </td>
876<td>
877              <p>
878                <a href="http://www.boost.org/libs/local_function" target="_top">Boost.LocalFunction</a>
879              </p>
880            </td>
881<td>
882              <p>
883                <a href="../../../example/profile_local_function.cpp" target="_top"><code class="literal">profile_local_function.cpp</code></a>
884              </p>
885            </td>
886</tr>
887<tr>
888<td>
889              <p>
890                <span class="inlinemediaobject"><img src="../../../example/profile_legend_local_function_inline.png" alt="profile_legend_local_function_inline"></span>
891              </p>
892            </td>
893<td>
894              <p>
895                <a href="http://www.boost.org/libs/local_function" target="_top">Boost.LocalFunction</a>
896                inline
897              </p>
898            </td>
899<td>
900              <p>
901                <a href="../../../example/profile_local_function_inline.cpp" target="_top"><code class="literal">profile_local_function_inline.cpp</code></a>
902              </p>
903            </td>
904</tr>
905<tr>
906<td>
907              <p>
908                <span class="inlinemediaobject"><img src="../../../example/profile_legend_cxx11_lambda.png" alt="profile_legend_cxx11_lambda"></span>
909              </p>
910            </td>
911<td>
912              <p>
913                <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
914                Lambda Function <a href="#ftn.boost_localfunction.alternatives.f0" class="footnote" name="boost_localfunction.alternatives.f0"><sup class="footnote">[a]</sup></a>
915              </p>
916            </td>
917<td>
918              <p>
919                <a href="../../../example/profile_cxx11_lambda.cpp" target="_top"><code class="literal">profile_cxx11_lambda.cpp</code></a>
920              </p>
921            </td>
922</tr>
923<tr>
924<td>
925              <p>
926                <span class="inlinemediaobject"><img src="../../../example/profile_legend_local_functor.png" alt="profile_legend_local_functor"></span>
927              </p>
928            </td>
929<td>
930              <p>
931                Local Functor
932              </p>
933            </td>
934<td>
935              <p>
936                <a href="../../../example/profile_local_functor.cpp" target="_top"><code class="literal">profile_local_functor.cpp</code></a>
937              </p>
938            </td>
939</tr>
940<tr>
941<td>
942              <p>
943                <span class="inlinemediaobject"><img src="../../../example/profile_legend_global_functor.png" alt="profile_legend_global_functor"></span>
944              </p>
945            </td>
946<td>
947              <p>
948                Global Functor
949              </p>
950            </td>
951<td>
952              <p>
953                <a href="../../../example/profile_global_functor.cpp" target="_top"><code class="literal">profile_global_functor.cpp</code></a>
954              </p>
955            </td>
956</tr>
957<tr>
958<td>
959              <p>
960                <span class="inlinemediaobject"><img src="../../../example/profile_legend_phoenix.png" alt="profile_legend_phoenix"></span>
961              </p>
962            </td>
963<td>
964              <p>
965                <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a>
966              </p>
967            </td>
968<td>
969              <p>
970                <a href="../../../example/profile_phoenix.cpp" target="_top"><code class="literal">profile_phoenix.cpp</code></a>
971              </p>
972            </td>
973</tr>
974</tbody>
975<tbody class="footnotes"><tr><td colspan="3"><div id="ftn.boost_localfunction.alternatives.f0" class="footnote"><p><a href="#boost_localfunction.alternatives.f0" class="para"><sup class="para">[a] </sup></a>
976                  Measurements available only for <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
977                  compilers.
978                </p></div></td></tr></tbody>
979</table></div>
980<div class="informaltable"><table class="table">
981<colgroup><col></colgroup>
982<thead><tr><th>
983              <p>
984                GCC 4.5.3 With C++11 Lambda Functions and "Local Classes as
985                Template Parameters" (<code class="literal">bjam cxxflags=-std=c++0x ...</code>)
986              </p>
987            </th></tr></thead>
988<tbody>
989<tr><td>
990              <p>
991                <span class="bold"><strong>Compiled with <code class="literal">bjam release ...</code>
992                for maximum optimization (<code class="literal">-O3 -finline-functions</code>)</strong></span>
993                <span class="inlinemediaobject"><img src="../../../example/profile_gcc_cxx11_release.png" width="1170" alt="profile_gcc_cxx11_release"></span>
994              </p>
995            </td></tr>
996<tr><td>
997              <p>
998                <span class="bold"><strong>Compiled with <code class="literal">bjam debug ...</code>
999                for no optimization (<code class="literal">-O0 -fno-inline</code>)</strong></span>
1000                <span class="inlinemediaobject"><img src="../../../example/profile_gcc_cxx11_debug.png" width="1170" alt="profile_gcc_cxx11_debug"></span>
1001              </p>
1002            </td></tr>
1003</tbody>
1004</table></div>
1005<div class="informaltable"><table class="table">
1006<colgroup><col></colgroup>
1007<thead><tr><th>
1008              <p>
1009                MSVC 8.0 With "Local Classes as Template Parameters" (Without
1010                C++11 Lambda Functions)
1011              </p>
1012            </th></tr></thead>
1013<tbody>
1014<tr><td>
1015              <p>
1016                <span class="bold"><strong>Compiled with <code class="literal">bjam release ...</code>
1017                for maximum optimization (<code class="literal">/O2 /Ob2</code>)</strong></span>
1018                <span class="inlinemediaobject"><img src="../../../example/profile_msvc_release.png" width="1170" alt="profile_msvc_release"></span>
1019              </p>
1020            </td></tr>
1021<tr><td>
1022              <p>
1023                <span class="bold"><strong>Compiled with <code class="literal">bjam debug ...</code>
1024                for no optimization (<code class="literal">/Od /Ob0</code>)</strong></span> <span class="inlinemediaobject"><img src="../../../example/profile_msvc_debug.png" width="1170" alt="profile_msvc_debug"></span>
1025              </p>
1026            </td></tr>
1027</tbody>
1028</table></div>
1029<div class="informaltable"><table class="table">
1030<colgroup><col></colgroup>
1031<thead><tr><th>
1032              <p>
1033                GCC 4.3.4 With <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>
1034                Only (Without <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>
1035                Lambda Functions and Without "Local Classes as Template Parameters")
1036              </p>
1037            </th></tr></thead>
1038<tbody>
1039<tr><td>
1040              <p>
1041                <span class="bold"><strong>Compiled with <code class="literal">bjam release ...</code>
1042                for maximum optimization (<code class="literal">-O3 -finline-functions</code>)</strong></span>
1043                <span class="inlinemediaobject"><img src="../../../example/profile_gcc_release.png" width="1170" alt="profile_gcc_release"></span>
1044              </p>
1045            </td></tr>
1046<tr><td>
1047              <p>
1048                <span class="bold"><strong>Compiled with <code class="literal">bjam debug ...</code>
1049                for no optimization (<code class="literal">-O0 -fno-inline</code>)</strong></span>
1050                <span class="inlinemediaobject"><img src="../../../example/profile_gcc_debug.png" width="1170" alt="profile_gcc_debug"></span>
1051              </p>
1052            </td></tr>
1053</tbody>
1054</table></div>
1055</div>
1056<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
1057<td align="left"></td>
1058<td align="right"><div class="copyright-footer">Copyright © 2009-2012 Lorenzo
1059      Caminiti<p>
1060        Distributed under the Boost Software License, Version 1.0 (see accompanying
1061        file LICENSE_1_0.txt or a copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
1062      </p>
1063</div></td>
1064</tr></table>
1065<hr>
1066<div class="spirit-nav">
1067<a accesskey="p" href="examples.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.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="no_variadic_macros.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
1068</div>
1069</body>
1070</html>
1071