UNPKG

boost-react-native-bundle

Version:

Boost library as in https://sourceforge.net/projects/boost/files/boost/1.57.0/

725 lines (691 loc) 70.5 kB
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> <title>Annex: Alternatives</title> <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css"> <meta name="generator" content="DocBook XSL Stylesheets V1.76.1"> <link rel="home" href="../index.html" title="Chapter&#160;1.&#160;Boost.LocalFunction 1.0.0"> <link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.LocalFunction 1.0.0"> <link rel="prev" href="examples.html" title="Examples"> <link rel="next" href="no_variadic_macros.html" title="Annex: No Variadic Macros"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table cellpadding="2" width="100%"><tr> <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td> <td align="center"><a href="../../../../../index.html">Home</a></td> <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td> <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> <td align="center"><a href="../../../../../more/index.htm">More</a></td> </tr></table> <hr> <div class="spirit-nav"> <a accesskey="p" href="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> </div> <div class="section boost_localfunction_alternatives"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> <a name="boost_localfunction.alternatives"></a><a class="link" href="alternatives.html" title="Annex: Alternatives">Annex: Alternatives</a> </h2></div></div></div> <p> This section compares the features offered by this library with similar features offered by C++ and by other libraries. </p> <h4> <a name="boost_localfunction.alternatives.h0"></a> <span><a name="boost_localfunction.alternatives.features"></a></span><a class="link" href="alternatives.html#boost_localfunction.alternatives.features">Features</a> </h4> <p> The following table compares local function features. </p> <div class="informaltable"><table class="table"> <colgroup> <col> <col> <col> <col> <col> <col> </colgroup> <thead><tr> <th> <p> Local Function Feature </p> </th> <th> <p> Boost.LocalFunction </p> </th> <th> <p> C++11 Lambda Function (Not C++03) </p> </th> <th> <p> Local Functor </p> </th> <th> <p> Global Functor (Not Local) </p> </th> <th> <p> Boost.Phoenix </p> </th> </tr></thead> <tbody> <tr> <td> <p> <span class="emphasis"><em>Can be defined locally</em></span> </p> </td> <td> <p> Yes. </p> </td> <td> <p> Yes. </p> </td> <td> <p> Yes. </p> </td> <td> <p> No. Therefore this not really an alternative implementation of local functions but it is listed here just for comparison. </p> </td> <td> <p> Yes. </p> </td> </tr> <tr> <td> <p> <span class="emphasis"><em>Can be defined using C++ statement syntax</em></span> </p> </td> <td> <p> Yes. Plus eventual compiler errors and debugging retain their usual meaning and format. </p> </td> <td> <p> Yes. Plus eventual compiler errors and debugging retain their usual meaning and format. </p> </td> <td> <p> Yes. Plus eventual compiler errors and debugging retain their usual meaning and format. </p> </td> <td> <p> Yes. Plus eventual compiler errors and debugging retain their usual meaning and format. </p> </td> <td> <p> No (it uses C++ <a href="http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Expression-template" target="_top">expression template</a> syntax). </p> </td> </tr> <tr> <td> <p> <span class="emphasis"><em>Can be defined within expressions</em></span> </p> </td> <td> <p> No. It can be defined only within declarations. </p> </td> <td> <p> Yes (plus the local function can be unnamed). </p> </td> <td> <p> No. It can be defined only within declarations. </p> </td> <td> <p> No. It can be defined only within declarations. </p> </td> <td> <p> Yes (plus the local function can be unnamed). </p> </td> </tr> <tr> <td> <p> <span class="emphasis"><em>Can be passed as template parameter (e.g., to STL algorithms)</em></span> </p> </td> <td> <p> Yes. The <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> standard does not allow to pass local types as template parameters (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a>) but this library implements a "trick" to get around this limitation (see the <a class="link" href="implementation.html" title="Annex: Implementation">Implementation</a> section). </p> </td> <td> <p> Yes. </p> </td> <td> <p> No on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> compilers (but yes on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> 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>). </p> </td> <td> <p> Yes. </p> </td> <td> <p> Yes. </p> </td> </tr> <tr> <td> <p> <span class="emphasis"><em>Access variables in scope</em></span> </p> </td> <td> <p> Yes. The variable names are repeated in the function declaration so they can be bound by value, by constant value, by reference, and by constant reference (the object <code class="computeroutput"><span class="keyword">this</span></code> can also be bound using <code class="computeroutput"><span class="identifier">this_</span></code>). </p> </td> <td> <p> Yes. The variable names are repeated in the function declaration (plus there is a short-hand syntax to bind all variables in scope at once) so they can be bound by constant value and by reference (the object <code class="computeroutput"><span class="keyword">this</span></code> can also be bound). However, variables cannot be bound by constant references (see below). </p> </td> <td> <p> No. Programmers must manually program functor data members and explicitly specify their types to access variables in scope. </p> </td> <td> <p> No. Programmers must manually program functor data members and explicitly specify their types to access variables in scope. </p> </td> <td> <p> Yes. Variables in scope are accessible as usual within expressions (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 by constant reference). </p> </td> </tr> <tr> <td> <p> <span class="emphasis"><em><a href="http://en.wikipedia.org/wiki/Type_polymorphism#Parametric_polymorphism" target="_top">Polymorphic</a> in the function parameter type</em></span> </p> </td> <td> <p> No (local functions cannot be function templates). </p> </td> <td> <p> No (<a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> lambdas cannot be function templates). </p> </td> <td> <p> No (local classes cannot have member function templates). </p> </td> <td> <p> Yes. </p> </td> <td> <p> Yes. </p> </td> </tr> </tbody> </table></div> <p> <span class="bold"><strong>C++11 Lambda Function</strong></span> </p> <p> <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 lambda functions</a> have most of the features of this library plus some additional feature (see also the example in the <a class="link" href="../index.html#boost_localfunction.introduction" title="Introduction">Introduction</a> section): </p> <div class="itemizedlist"><ul class="itemizedlist" type="disc"> <li class="listitem"> <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 lambda functions</a> can be defined within expressions while this library local functions can only be defined at declaration scope. </li> <li class="listitem"> <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 lambda functions</a> are only supported by the <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> standard so they are not supported by all C++ compilers. This library local functions can be programmed also on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 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 lambda functions</a> on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> compilers). </li> <li class="listitem"> <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 lambda functions</a> do not allow to bind variables in scope by constant 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 lambda functions</a> can bind a variable by constant only if the variable is <code class="computeroutput"><span class="identifier">CopyConstructible</span></code> and the binding requires a (potentially expensive) extra copy operation. Constant reference binding is instead supported by this library. </li> <li class="listitem"> <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 lambda functions</a> do not allow to bind data members selectively without binding also the object <code class="computeroutput"><span class="keyword">this</span></code> while this library local functions can bind either selected data members or the entire object <code class="computeroutput"><span class="keyword">this</span></code> (using <code class="computeroutput"><span class="identifier">this_</span></code>). </li> <li class="listitem"> <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 lambda functions</a> provide a short-hand syntax to bind all variables in scope at once (<code class="computeroutput"><span class="special">&amp;</span></code> or <code class="computeroutput"><span class="special">=</span></code>) while this library local function always require to bind variables naming them one-by-one. </li> </ul></div> <p> 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> and <a href="../../../example/noncopyable_local_function.cpp" target="_top"><code class="literal">noncopyable_local_function.cpp</code></a>): </p> <div class="informaltable"><table class="table"> <colgroup> <col> <col> </colgroup> <thead><tr> <th> <p> C++11 Lambda Function </p> </th> <th> <p> Boost.LocalFunction </p> </th> </tr></thead> <tbody><tr> <td> <p> </p> <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> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> <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> <span class="special">};</span> <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="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span> <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> <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> <span class="special">};</span> <span class="identifier">f</span><span class="special">();</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span> </pre> <p> </p> </td> <td> <p> </p> <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> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> <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> <span class="special">};</span> <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> <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="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span> <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> <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> <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> <span class="identifier">f</span><span class="special">();</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span> </pre> <p> </p> </td> </tr></tbody> </table></div> <p> 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> and <a href="../../../example/expensive_copy_local_function.cpp" target="_top"><code class="literal">expensive_copy_local_function.cpp</code></a>): </p> <div class="informaltable"><table class="table"> <colgroup> <col> <col> </colgroup> <thead><tr> <th> <p> C++11 Lambda Function </p> </th> <th> <p> Boost.LocalFunction </p> </th> </tr></thead> <tbody><tr> <td> <p> </p> <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="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> <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> <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> <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> <span class="special">}</span> <span class="special">};</span> <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="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span> <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> <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> <span class="special">};</span> <span class="identifier">f</span><span class="special">();</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span> </pre> <p> </p> </td> <td> <p> </p> <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="keyword">int</span> <span class="identifier">i</span><span class="special">;</span> <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> <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> <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> <span class="special">}</span> <span class="special">};</span> <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> <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="identifier">n</span> <span class="identifier">x</span><span class="special">(-</span><span class="number">1</span><span class="special">);</span> <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> <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> <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> <span class="identifier">f</span><span class="special">();</span> <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> <span class="special">}</span> </pre> <p> </p> </td> </tr></tbody> </table></div> <p> 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 lambda functions</a>, the best alternative might be to bind an extra local variable declared constant and initialized to the original variable (for example, 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 lambda functions</a> in the <a class="link" href="examples.html" title="Examples">Examples</a> section). </p> <p> <span class="bold"><strong>Local Functor</strong></span> </p> <p> The following example compares local functions with C++ local functors (see also <a href="../../../example/add_local_functor.cpp" target="_top"><code class="literal">add_local_functor.cpp</code></a> and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>): </p> <div class="informaltable"><table class="table"> <colgroup> <col> <col> </colgroup> <thead><tr> <th> <p> Local Functor </p> </th> <th> <p> Boost.LocalFunction </p> </th> </tr></thead> <tbody><tr> <td> <p> </p> <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="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="keyword">struct</span> <span class="identifier">local_add</span> <span class="special">{</span> <span class="comment">// Unfortunately, boilerplate code to program the class.</span> <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> <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> <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> <span class="special">}</span> <span class="keyword">private</span><span class="special">:</span> <span class="comment">// Unfortunately, cannot bind so repeat variable types.</span> <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> <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> <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> <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <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> <span class="comment">// Unfortunately, cannot pass as template parameter to `std::for_each`.</span> <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> <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="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span> <span class="special">}</span> </pre> <p> </p> </td> <td> <p> </p> <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> <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> <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> <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> <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> <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> <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> <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> <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> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span> <span class="special">}</span> </pre> <p> </p> </td> </tr></tbody> </table></div> <p> <span class="bold"><strong>Global Functor</strong></span> </p> <p> The following example compares local functions with C++ global functors (see also <a href="../../../example/add_global_functor.cpp" target="_top"><code class="literal">add_global_functor.cpp</code></a> and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>): </p> <div class="informaltable"><table class="table"> <colgroup> <col> <col> </colgroup> <thead><tr> <th> <p> Global Functor </p> </th> <th> <p> Boost.LocalFunction </p> </th> </tr></thead> <tbody><tr> <td> <p> </p> <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> <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> <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> <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> <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> <span class="special">}</span> <span class="keyword">private</span><span class="special">:</span> <span class="comment">// Unfortunately, cannot bind so repeat variable types.</span> <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> <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> <span class="special">};</span> <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="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="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> <span class="identifier">add</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <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> <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> <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="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span> <span class="special">}</span> </pre> <p> </p> </td> <td> <p> </p> <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> <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> <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> <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> <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> <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> <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> <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> <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> <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span> <span class="special">}</span> </pre> <p> </p> </td> </tr></tbody> </table></div> <p> However, note that global functors do not allow to define the function locally so they are not a real alternative implementation of local functions. </p> <p> <span class="bold"><strong>Boost.Phoenix</strong></span> </p> <p> The following example compares local functions with <a href="http://www.boost.org/libs/phoenix" target="_top">Boost.Phoenix</a> (see also <a href="../../../example/add_phoenix.cpp" target="_top"><code class="literal">add_phoenix.cpp</code></a> and <a href="../../../test/add.cpp" target="_top"><code class="literal">add.cpp</code></a>): </p> <div class="informaltable"><table class="table"> <colgroup> <col> <col> </colgroup> <thead><tr> <th> <p> Boost.Phoenix </p> </th> <th> <p> Boost.LocalFunction </p> </th> </tr></thead> <tbody><tr> <td> <p> </p> <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="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> <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> <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> <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> <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> <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="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> <span class="comment">// Passed to template, `factor` by constant, and defined in expression.</span> <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> <span class="comment">// Unfortunately, body cannot use C++ statement syntax.</span> <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> <span class="special">]);</span> <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="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span> <span class="special">}</span> </pre> <p> </p> </td> <td> <p> </p> <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