1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Advanced Topics</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="tutorial.html" title="Tutorial"> 10<link rel="next" href="examples.html" title="Examples"> 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="tutorial.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="examples.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.advanced_topics"></a><a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced Topics</a> 28</h2></div></div></div> 29<div class="toc"><dl class="toc"> 30<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.default_parameters">Default 31 Parameters</a></span></dt> 32<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.commas_and_symbols_in_macros">Commas 33 and Symbols in Macros</a></span></dt> 34<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.assignments_and_returns">Assignments 35 and Returns</a></span></dt> 36<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.nesting">Nesting</a></span></dt> 37<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.accessing_types__concepts__etc_">Accessing 38 Types (concepts, etc)</a></span></dt> 39<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.specifying_types__no_boost_typeof_">Specifying 40 Types (no Boost.Typeof)</a></span></dt> 41<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.inlining">Inlining</a></span></dt> 42<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.recursion">Recursion</a></span></dt> 43<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.overloading">Overloading</a></span></dt> 44<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.exception_specifications">Exception 45 Specifications</a></span></dt> 46<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.storage_classifiers">Storage 47 Classifiers</a></span></dt> 48<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.same_line_expansions">Same 49 Line Expansions</a></span></dt> 50<dt><span class="section"><a href="advanced_topics.html#boost_localfunction.advanced_topics.limitations__operators__etc_">Limitations 51 (operators, etc)</a></span></dt> 52</dl></div> 53<p> 54 This section illustrates advanced usage of this library. At the bottom there 55 is also a list of known limitations of this library. 56 </p> 57<div class="section"> 58<div class="titlepage"><div><div><h3 class="title"> 59<a name="boost_localfunction.advanced_topics.default_parameters"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.default_parameters" title="Default Parameters">Default 60 Parameters</a> 61</h3></div></div></div> 62<p> 63 This library allows to specify default values for the local function parameters. 64 However, the usual C++ syntax for default parameters that uses the assignment 65 symbol <code class="computeroutput"><span class="special">=</span></code> cannot be used. <a href="#ftn.boost_localfunction.advanced_topics.default_parameters.f0" class="footnote" name="boost_localfunction.advanced_topics.default_parameters.f0"><sup class="footnote">[17]</sup></a> The keyword <code class="computeroutput"><span class="keyword">default</span></code> 66 is used instead: 67 </p> 68<pre class="programlisting"><code class="literal"><span class="emphasis"><em>parameter-type parameter-name</em></span></code><span class="special">,</span> <span class="keyword">default</span> <code class="literal"><span class="emphasis"><em>parameter-default-value</em></span></code><span class="special">,</span> <span class="special">...</span> 69</pre> 70<p> 71 For example, let's program a local function <code class="computeroutput"><span class="identifier">add</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> 72 <span class="identifier">y</span><span class="special">)</span></code> 73 where the second parameter <code class="computeroutput"><span class="identifier">y</span></code> 74 is optional and has a default value of <code class="computeroutput"><span class="number">2</span></code> 75 (see also <a href="../../../test/add_default.cpp" target="_top"><code class="literal">add_default.cpp</code></a>): 76 </p> 77<p> 78</p> 79<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">,</span> <span class="keyword">default</span> <span class="number">2</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Default parameter.</span> 80 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> 81<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> 82 83<span class="identifier">BOOST_TEST</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="special">==</span> <span class="number">3</span><span class="special">);</span> 84</pre> 85<p> 86 </p> 87<p> 88 Programmers can define a <code class="computeroutput"><span class="identifier">WITH_DEFAULT</span></code> 89 macro similar to the following if they think it improves readability over 90 the above syntax (see also <a href="../../../test/add_with_default.cpp" target="_top"><code class="literal">add_with_default.cpp</code></a>): 91 <a href="#ftn.boost_localfunction.advanced_topics.default_parameters.f1" class="footnote" name="boost_localfunction.advanced_topics.default_parameters.f1"><sup class="footnote">[18]</sup></a> 92 </p> 93<p> 94</p> 95<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">WITH_DEFAULT</span> <span class="special">,</span> <span class="keyword">default</span> 96</pre> 97<p> 98 </p> 99<p> 100</p> 101<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span> <span class="identifier">WITH_DEFAULT</span> <span class="number">2</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Default.</span> 102 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> 103<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> 104 105<span class="identifier">BOOST_TEST</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="special">==</span> <span class="number">3</span><span class="special">);</span> 106</pre> 107<p> 108 </p> 109</div> 110<div class="section"> 111<div class="titlepage"><div><div><h3 class="title"> 112<a name="boost_localfunction.advanced_topics.commas_and_symbols_in_macros"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.commas_and_symbols_in_macros" title="Commas and Symbols in Macros">Commas 113 and Symbols in Macros</a> 114</h3></div></div></div> 115<p> 116 The C++ preprocessor does not allow commas <code class="computeroutput"><span class="special">,</span></code> 117 within macro parameters unless they are wrapped by round parenthesis <code class="computeroutput"><span class="special">()</span></code> (see the <a href="http://www.boost.org/libs/utility/identity_type" target="_top">Boost.Utility/IdentityType</a> 118 documentation for details). Therefore, using commas within local function 119 parameters and bindings will generate (cryptic) preprocessor errors unless 120 they are wrapped with an extra set of round parenthesis <code class="computeroutput"><span class="special">()</span></code> 121 as explained here. 122 </p> 123<div class="note"><table border="0" summary="Note"> 124<tr> 125<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 126<th align="left">Note</th> 127</tr> 128<tr><td align="left" valign="top"><p> 129 Also macro parameters with commas wrapped by angular parenthesis <code class="computeroutput"><span class="special"><></span></code> (templates, etc) or square parenthesis 130 <code class="computeroutput"><span class="special">[]</span></code> (multidimensional array 131 access, etc) need to be wrapped by the extra round parenthesis <code class="computeroutput"><span class="special">()</span></code> as explained here (this is because the 132 preprocessor only recognizes the round parenthesis and it does not recognize 133 angular, square, or any other type of parenthesis). However, macro parameters 134 with commas which are already wrapped by round parenthesis <code class="computeroutput"><span class="special">()</span></code> are fine (function calls, some value 135 expressions, etc). 136 </p></td></tr> 137</table></div> 138<p> 139 In addition, local function parameter types cannot start with non-alphanumeric 140 symbols (alphanumeric symbols are <code class="computeroutput"><span class="identifier">A</span><span class="special">-</span><span class="identifier">Z</span></code>, <code class="computeroutput"><span class="identifier">a</span><span class="special">-</span><span class="identifier">z</span></code>, 141 and <code class="computeroutput"><span class="number">0</span><span class="special">-</span><span class="number">9</span></code>). <a href="#ftn.boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f0" class="footnote" name="boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f0"><sup class="footnote">[19]</sup></a> The library will generate (cryptic) preprocessor errors if a 142 parameter type starts with a non-alphanumeric symbol. 143 </p> 144<p> 145 Let's consider the following example: 146 </p> 147<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 148 <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>&</span> <span class="identifier">m</span><span class="special">,</span> <span class="comment">// (1) Error.</span> 149 <span class="special">::</span><span class="identifier">sign_t</span> <span class="identifier">sign</span><span class="special">,</span> <span class="comment">// (2) Error.</span> 150 <span class="keyword">const</span> <span class="identifier">size_t</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">,</span> 151 <span class="keyword">default</span> <span class="identifier">key_sizeof</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> <span class="comment">// (3) Error.</span> 152 <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">separator</span><span class="special">,</span> <span class="keyword">default</span> <span class="identifier">cat</span><span class="special">(</span><span class="string">":"</span><span class="special">,</span> <span class="string">" "</span><span class="special">)</span> <span class="comment">// (4) OK.</span> 153<span class="special">)</span> <span class="special">{</span> 154 <span class="special">...</span> 155<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> 156</pre> 157<p> 158 <span class="bold"><strong>(1)</strong></span> The parameter type <code class="computeroutput"><span class="keyword">const</span> 159 <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>&</span></code> contains a comma <code class="computeroutput"><span class="special">,</span></code> 160 after the first template parameter <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. 161 This comma is not wrapped by any round parenthesis <code class="computeroutput"><span class="special">()</span></code> 162 thus it will cause a preprocessor error. <a href="#ftn.boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f1" class="footnote" name="boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f1"><sup class="footnote">[20]</sup></a> The <a href="http://www.boost.org/libs/utility/identity_type" target="_top">Boost.Utility/IdentityType</a> 163 macro <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span></code><code class="literal"><span class="emphasis"><em>type-with-commas</em></span></code><code class="computeroutput"><span class="special">))</span></code> defined in the <code class="literal">boost/utility/identity_type.hpp</code> 164 header can be used to wrap a type within extra parenthesis <code class="computeroutput"><span class="special">()</span></code> so to overcome this problem: 165 </p> 166<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">identity_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 167 168<span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 169 <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>&))</span> <span class="identifier">m</span><span class="special">,</span> <span class="comment">// OK.</span> 170 <span class="special">...</span> 171<span class="special">)</span> <span class="special">{</span> 172 <span class="special">...</span> 173<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> 174</pre> 175<p> 176 This macro expands to an expression that evaluates (at compile-time) exactly 177 to the specified type (furthermore, this macro does not use variadic macros 178 so it works on any <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 179 compiler). Note that a total of two set of parenthesis <code class="computeroutput"><span class="special">()</span></code> 180 are needed: The parenthesis to invoke the <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(...)</span></code> macro plus the parenthesis to wrap the 181 type expression (and therefore any comma <code class="computeroutput"><span class="special">,</span></code> 182 that it contains) passed as parameter to the <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((...))</span></code> macro. Finally, the <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span></code> macro must be prefixed 183 by the <code class="computeroutput"><span class="keyword">typename</span></code> keyword <code class="computeroutput"><span class="keyword">typename</span> <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">(</span></code><code class="literal"><span class="emphasis"><em>parenthesized-type</em></span></code><code class="computeroutput"><span class="special">)</span></code> when used together with the <code class="computeroutput">BOOST_LOCAL_FUNCTION_TPL</code> 184 macro within templates. 185 </p> 186<div class="note"><table border="0" summary="Note"> 187<tr> 188<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 189<th align="left">Note</th> 190</tr> 191<tr><td align="left" valign="top"><p> 192 Often, there might be better ways to overcome this limitation that lead 193 to code which is more readable than the one using the <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span></code> 194 macro. 195 </p></td></tr> 196</table></div> 197<p> 198 For example, in this case a <code class="computeroutput"><span class="keyword">typedef</span></code> 199 from the enclosing scope could have been used to obtain the following valid 200 and perhaps more readable code: 201 </p> 202<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">></span> <span class="identifier">map_type</span><span class="special">;</span> 203<span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 204 <span class="keyword">const</span> <span class="identifier">map_type</span><span class="special">&</span> <span class="identifier">m</span><span class="special">,</span> <span class="comment">// OK (and more readable).</span> 205 <span class="special">...</span> 206<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> 207</pre> 208<p> 209 <span class="bold"><strong>(2)</strong></span> The parameter type <code class="computeroutput"><span class="special">::</span><span class="identifier">sign_t</span></code> starts with the non-alphanumeric 210 symbols <code class="computeroutput"><span class="special">::</span></code> thus it will generate 211 preprocessor errors if used as a local function parameter type. The <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span></code> macro can also be used 212 to overcome this issue: 213 </p> 214<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 215 <span class="special">...</span> 216 <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((::</span><span class="identifier">sign_t</span><span class="special">))</span> <span class="identifier">sign</span><span class="special">,</span> <span class="comment">// OK.</span> 217 <span class="special">...</span> 218<span class="special">)</span> <span class="special">{</span> 219 <span class="special">...</span> 220<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> 221</pre> 222<div class="note"><table border="0" summary="Note"> 223<tr> 224<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 225<th align="left">Note</th> 226</tr> 227<tr><td align="left" valign="top"><p> 228 Often, there might be better ways to overcome this limitation that lead 229 to code which is more readable than the one using the <code class="computeroutput"><span class="identifier">BOOST_IDENTITY_TYPE</span></code> 230 macro. 231 </p></td></tr> 232</table></div> 233<p> 234 For example, in this case the symbols <code class="computeroutput"><span class="special">::</span></code> 235 could have been simply dropped to obtain the following valid and perhaps 236 more readable code: 237 </p> 238<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 239 <span class="special">...</span> 240 <span class="identifier">sign_t</span> <span class="identifier">sign</span><span class="special">,</span> <span class="comment">// OK (and more readable).</span> 241 <span class="special">...</span> 242<span class="special">)</span> <span class="special">{</span> 243 <span class="special">...</span> 244<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> 245</pre> 246<p> 247 <span class="bold"><strong>(3)</strong></span> The default parameter value <code class="computeroutput"><span class="identifier">key_sizeof</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>::</span><span class="identifier">value</span></code> 248 contains a comma <code class="computeroutput"><span class="special">,</span></code> after the 249 first template parameter <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>. 250 Again, this comma is not wrapped by any parenthesis <code class="computeroutput"><span class="special">()</span></code> 251 so it will cause a preprocessor error. Because this is a value expression 252 (and not a type expression), it can simply be wrapped within an extra set 253 of round parenthesis <code class="computeroutput"><span class="special">()</span></code>: 254 </p> 255<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 256 <span class="special">...</span> 257 <span class="keyword">const</span> <span class="identifier">size_t</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">,</span> 258 <span class="keyword">default</span> <span class="special">(</span><span class="identifier">key_sizeof</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>::</span><span class="identifier">value</span><span class="special">),</span> <span class="comment">// OK.</span> 259 <span class="special">...</span> 260<span class="special">)</span> <span class="special">{</span> 261 <span class="special">...</span> 262<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> 263</pre> 264<p> 265 <span class="bold"><strong>(4)</strong></span> The default parameter value <code class="computeroutput"><span class="identifier">cat</span><span class="special">(</span><span class="string">":"</span><span class="special">,</span> <span class="string">" "</span><span class="special">)</span></code> is instead fine because it contains a comma 266 <code class="computeroutput"><span class="special">,</span></code> which is already wrapped by 267 the parenthesis <code class="computeroutput"><span class="special">()</span></code> of the function 268 call <code class="computeroutput"><span class="identifier">cat</span><span class="special">(...)</span></code>. 269 </p> 270<p> 271 Consider the following complete example (see also <a href="../../../test/macro_commas.cpp" target="_top"><code class="literal">macro_commas.cpp</code></a>): 272 </p> 273<p> 274</p> 275<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 276 <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>&))</span> <span class="identifier">m</span><span class="special">,</span> 277 <span class="identifier">BOOST_IDENTITY_TYPE</span><span class="special">((::</span><span class="identifier">sign_t</span><span class="special">))</span> <span class="identifier">sign</span><span class="special">,</span> 278 <span class="keyword">const</span> <span class="identifier">size_t</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">,</span> 279 <span class="keyword">default</span> <span class="special">(</span><span class="identifier">key_sizeof</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>::</span><span class="identifier">value</span><span class="special">),</span> 280 <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">separator</span><span class="special">,</span> <span class="keyword">default</span> <span class="identifier">cat</span><span class="special">(</span><span class="string">":"</span><span class="special">,</span> <span class="string">" "</span><span class="special">)</span> 281<span class="special">)</span> <span class="special">{</span> 282 <span class="comment">// Do something...</span> 283<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> 284</pre> 285<p> 286 </p> 287</div> 288<div class="section"> 289<div class="titlepage"><div><div><h3 class="title"> 290<a name="boost_localfunction.advanced_topics.assignments_and_returns"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.assignments_and_returns" title="Assignments and Returns">Assignments 291 and Returns</a> 292</h3></div></div></div> 293<p> 294 Local functions are function objects so it is possible to assign them to 295 other functors like <a href="http://www.boost.org/libs/function" target="_top">Boost.Function</a>'s 296 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span></code> in order to store the local function 297 into a variable, pass it as a parameter to another function, or return it 298 from the enclosing function. 299 </p> 300<p> 301 For example (see also <a href="../../../test/return_assign.cpp" target="_top"><code class="literal">return_assign.cpp</code></a>): 302 </p> 303<p> 304</p> 305<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">call1</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">></span> <span class="identifier">f</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">f</span><span class="special">(</span><span class="number">1</span><span class="special">)</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span> <span class="special">}</span> 306<span class="keyword">void</span> <span class="identifier">call0</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">int</span> <span class="special">(</span><span class="keyword">void</span><span class="special">)></span> <span class="identifier">f</span><span class="special">)</span> <span class="special">{</span> <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">f</span><span class="special">()</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span> <span class="special">}</span> 307 308<span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)></span> <span class="identifier">linear</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">slope</span><span class="special">)</span> <span class="special">{</span> 309 <span class="keyword">int</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">&</span> <span class="identifier">slope</span><span class="special">,</span> 310 <span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">default</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">,</span> <span class="keyword">default</span> <span class="number">2</span><span class="special">)</span> <span class="special">{</span> 311 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">slope</span> <span class="special">*</span> <span class="identifier">y</span><span class="special">;</span> 312 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">lin</span><span class="special">)</span> 313 314 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)></span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">lin</span><span class="special">;</span> <span class="comment">// Assign to local variable.</span> 315 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">f</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="special">==</span> <span class="number">5</span><span class="special">);</span> 316 317 <span class="identifier">call1</span><span class="special">(</span><span class="identifier">lin</span><span class="special">);</span> <span class="comment">// Pass to other functions.</span> 318 <span class="identifier">call0</span><span class="special">(</span><span class="identifier">lin</span><span class="special">);</span> 319 320 <span class="keyword">return</span> <span class="identifier">lin</span><span class="special">;</span> <span class="comment">// Return.</span> 321<span class="special">}</span> 322 323<span class="keyword">void</span> <span class="identifier">call</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">{</span> 324 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span><span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)></span> <span class="identifier">f</span> <span class="special">=</span> <span class="identifier">linear</span><span class="special">(</span><span class="number">2</span><span class="special">);</span> 325 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">f</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="special">==</span> <span class="number">5</span><span class="special">);</span> 326<span class="special">}</span> 327</pre> 328<p> 329 </p> 330<div class="warning"><table border="0" summary="Warning"> 331<tr> 332<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td> 333<th align="left">Warning</th> 334</tr> 335<tr><td align="left" valign="top"><p> 336 As with <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 337 lambda functions</a>, programmers are responsible to ensure that bound 338 variables are valid in any scope where the local function object is called. 339 Returning and calling a local function outside its declaration scope will 340 lead to undefined behaviour if any of the bound variable is no longer valid 341 in the scope where the local function is called (see the <a class="link" href="examples.html" title="Examples">Examples</a> 342 section for more examples on the extra care needed when returning a local 343 function as a closure). It is always safe instead to call a local function 344 within its enclosing scope. 345 </p></td></tr> 346</table></div> 347<p> 348 In addition, a local function can bind and call other local functions. Local 349 functions should always be bound by constant reference <code class="computeroutput"><span class="keyword">const</span> 350 <span class="identifier">bind</span><span class="special">&</span></code> 351 to avoid unnecessary copies. For example, the following local function <code class="computeroutput"><span class="identifier">inc_sum</span></code> binds the local function <code class="computeroutput"><span class="identifier">inc</span></code> so <code class="computeroutput"><span class="identifier">inc_sum</span></code> 352 can call <code class="computeroutput"><span class="identifier">inc</span></code> (see aslo <a href="../../../test/transform.cpp" target="_top"><code class="literal">transform.cpp</code></a>): 353 </p> 354<p> 355</p> 356<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">offset</span> <span class="special">=</span> <span class="number">5</span><span class="special">;</span> 357<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">v</span><span class="special">;</span> 358<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">w</span><span class="special">;</span> 359 360<span class="keyword">for</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><=</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">v</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">i</span> <span class="special">*</span> <span class="number">10</span><span class="special">);</span> 361<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">v</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">==</span> <span class="number">10</span><span class="special">);</span> <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">v</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">==</span> <span class="number">20</span><span class="special">);</span> 362<span class="identifier">w</span><span class="special">.</span><span class="identifier">resize</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span> 363 364<span class="keyword">int</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">&</span> <span class="identifier">offset</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> 365 <span class="keyword">return</span> <span class="special">++</span><span class="identifier">i</span> <span class="special">+</span> <span class="identifier">offset</span><span class="special">;</span> 366<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">inc</span><span class="special">)</span> 367 368<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">w</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">inc</span><span class="special">);</span> 369<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">w</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">==</span> <span class="number">16</span><span class="special">);</span> <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">w</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">==</span> <span class="number">26</span><span class="special">);</span> 370 371<span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="identifier">bind</span><span class="special">&</span> <span class="identifier">inc</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">j</span><span class="special">)</span> <span class="special">{</span> 372 <span class="keyword">return</span> <span class="identifier">inc</span><span class="special">(</span><span class="identifier">i</span> <span class="special">+</span> <span class="identifier">j</span><span class="special">);</span> <span class="comment">// Call the other bound local function.</span> 373<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">inc_sum</span><span class="special">)</span> 374 375<span class="identifier">offset</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 376<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">w</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">inc_sum</span><span class="special">);</span> 377<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">v</span><span class="special">[</span><span class="number">0</span><span class="special">]</span> <span class="special">==</span> <span class="number">27</span><span class="special">);</span> <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">v</span><span class="special">[</span><span class="number">1</span><span class="special">]</span> <span class="special">==</span> <span class="number">47</span><span class="special">);</span> 378</pre> 379<p> 380 </p> 381</div> 382<div class="section"> 383<div class="titlepage"><div><div><h3 class="title"> 384<a name="boost_localfunction.advanced_topics.nesting"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.nesting" title="Nesting">Nesting</a> 385</h3></div></div></div> 386<p> 387 It is possible to nest local functions into one another. For example (see 388 also <a href="../../../test/nesting.cpp" target="_top"><code class="literal">nesting.cpp</code></a>): 389 </p> 390<p> 391</p> 392<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 393 394<span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="identifier">bind</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> 395 <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="identifier">bind</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Nested.</span> 396 <span class="identifier">x</span><span class="special">++;</span> 397 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">g</span><span class="special">)</span> 398 399 <span class="identifier">x</span><span class="special">--;</span> 400 <span class="identifier">g</span><span class="special">();</span> <span class="comment">// Nested local function call.</span> 401<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> 402 403<span class="identifier">f</span><span class="special">();</span> 404</pre> 405<p> 406 </p> 407</div> 408<div class="section"> 409<div class="titlepage"><div><div><h3 class="title"> 410<a name="boost_localfunction.advanced_topics.accessing_types__concepts__etc_"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.accessing_types__concepts__etc_" title="Accessing Types (concepts, etc)">Accessing 411 Types (concepts, etc)</a> 412</h3></div></div></div> 413<p> 414 This library never requires to explicitly specify the type of bound variables 415 (e.g., this reduces maintenance because the local function declaration and 416 definition do not have to change even if the bound variable types change 417 as long as the semantics of the local function remain valid). From within 418 local functions, programmers can access the type of a bound variable using 419 the following macro: 420 </p> 421<pre class="programlisting"><span class="identifier">BOOST_LOCAL_FUNCTION_TYPEOF</span><span class="special">(</span><span class="emphasis"><em>bound-variable-name</em></span><span class="special">)</span> 422</pre> 423<p> 424 The <code class="computeroutput">BOOST_LOCAL_FUNCTION_TYPEOF</code> 425 macro expands to a type expression that evaluates (at compile-time) to the 426 fully qualified type of the bound variable with the specified name. This 427 type expression is fully qualified in the sense that it will be constant 428 if the variable is bound by constant <code class="computeroutput"><span class="keyword">const</span> 429 <span class="identifier">bind</span><span class="special">[&]</span></code> 430 and it will also be a reference if the variable is bound by reference <code class="computeroutput"><span class="special">[</span><span class="keyword">const</span><span class="special">]</span> 431 <span class="identifier">bind</span><span class="special">&</span></code> 432 (if needed, programmers can remove the <code class="computeroutput"><span class="keyword">const</span></code> 433 and <code class="computeroutput"><span class="special">&</span></code> qualifiers using 434 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_const</span></code> and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span></code>, 435 see <a href="http://www.boost.org/libs/type_traits" target="_top">Boost.TypeTraits</a>). 436 </p> 437<p> 438 The deduced bound type can be used within the body to check concepts, declare 439 local variables, etc. For example (see also <a href="../../../test/typeof.cpp" target="_top"><code class="literal">typeof.cpp</code></a> 440 and <a href="../../../test/addable.hpp" target="_top"><code class="literal">addable.hpp</code></a>): 441 </p> 442<p> 443</p> 444<pre class="programlisting"><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> 445 446<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">&</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> 447 <span class="comment">// Type-of for concept checking.</span> 448 <span class="identifier">BOOST_CONCEPT_ASSERT</span><span class="special">((</span><span class="identifier">Addable</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span> 449 <span class="identifier">BOOST_LOCAL_FUNCTION_TYPEOF</span><span class="special">(</span><span class="identifier">sum</span><span class="special">)>::</span><span class="identifier">type</span><span class="special">>));</span> 450 <span class="comment">// Type-of for declarations.</span> 451 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span><span class="identifier">BOOST_LOCAL_FUNCTION_TYPEOF</span><span class="special">(</span> 452 <span class="identifier">factor</span><span class="special">)>::</span><span class="identifier">type</span> <span class="identifier">mult</span> <span class="special">=</span> <span class="identifier">factor</span> <span class="special">*</span> <span class="identifier">num</span><span class="special">;</span> 453 <span class="identifier">sum</span> <span class="special">+=</span> <span class="identifier">mult</span><span class="special">;</span> 454<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> 455 456<span class="identifier">add</span><span class="special">(</span><span class="number">6</span><span class="special">);</span> 457</pre> 458<p> 459 </p> 460<p> 461 Within templates, <code class="computeroutput">BOOST_LOCAL_FUNCTION_TYPEOF</code> 462 should not be prefixed by the <code class="computeroutput"><span class="keyword">typename</span></code> 463 keyword but eventual type manipulations need the <code class="computeroutput"><span class="keyword">typename</span></code> 464 prefix as usual (see also <a href="../../../test/typeof_template.cpp" target="_top"><code class="literal">typeof_template.cpp</code></a> 465 and <a href="../../../test/addable.hpp" target="_top"><code class="literal">addable.hpp</code></a>): 466 </p> 467<p> 468</p> 469<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 470<span class="identifier">T</span> <span class="identifier">calculate</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">factor</span><span class="special">)</span> <span class="special">{</span> 471 <span class="identifier">T</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 472 473 <span class="keyword">void</span> <span class="identifier">BOOST_LOCAL_FUNCTION_TPL</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">&</span> <span class="identifier">sum</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">num</span><span class="special">)</span> <span class="special">{</span> 474 <span class="comment">// Local function `TYPEOF` does not need `typename`.</span> 475 <span class="identifier">BOOST_CONCEPT_ASSERT</span><span class="special">((</span><span class="identifier">Addable</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">remove_reference</span><span class="special"><</span> 476 <span class="identifier">BOOST_LOCAL_FUNCTION_TYPEOF</span><span class="special">(</span><span class="identifier">sum</span><span class="special">)>::</span><span class="identifier">type</span><span class="special">>));</span> 477 <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> 478 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME_TPL</span><span class="special">(</span><span class="identifier">add</span><span class="special">)</span> 479 480 <span class="identifier">add</span><span class="special">(</span><span class="number">6</span><span class="special">);</span> 481 <span class="keyword">return</span> <span class="identifier">sum</span><span class="special">;</span> 482<span class="special">}</span> 483</pre> 484<p> 485 </p> 486<p> 487 In this context, it is best to use the <code class="computeroutput">BOOST_LOCAL_FUNCTION_TYPEOF</code> 488 macro instead of using <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 489 to reduce the number of times that <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 490 is invoked (either the library already internally used <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 491 once, in which case using this macro will not use <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 492 again, or the bound variable type is explicitly specified by programmers 493 as shown be below, in which case using this macro will not use <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 494 at all). 495 </p> 496<p> 497 Furthermore, within the local function body it possible to access the result 498 type using <code class="computeroutput"><span class="identifier">result_type</span></code>, the 499 type of the first parameter using <code class="computeroutput"><span class="identifier">arg1_type</span></code>, 500 the type of the second parameter using <code class="computeroutput"><span class="identifier">arg2_type</span></code>, 501 etc. <a href="#ftn.boost_localfunction.advanced_topics.accessing_types__concepts__etc_.f0" class="footnote" name="boost_localfunction.advanced_topics.accessing_types__concepts__etc_.f0"><sup class="footnote">[21]</sup></a> 502 </p> 503</div> 504<div class="section"> 505<div class="titlepage"><div><div><h3 class="title"> 506<a name="boost_localfunction.advanced_topics.specifying_types__no_boost_typeof_"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.specifying_types__no_boost_typeof_" title="Specifying Types (no Boost.Typeof)">Specifying 507 Types (no Boost.Typeof)</a> 508</h3></div></div></div> 509<p> 510 While not required, it is possible to explicitly specify the type of bound 511 variables so the library will not internally use <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 512 to automatically deduce the types. When specified, the bound variable type 513 must follow the <code class="computeroutput"><span class="identifier">bind</span></code> "keyword" 514 and it must be wrapped within round parenthesis <code class="computeroutput"><span class="special">()</span></code>: 515 </p> 516<pre class="programlisting"><span class="identifier">bind</span><span class="special">(</span><span class="emphasis"><em>variable-type</em></span><span class="special">)</span> <span class="emphasis"><em>variable-name</em></span> <span class="comment">// Bind by value with explicit type.</span> 517<span class="identifier">bind</span><span class="special">(</span><span class="emphasis"><em>variable-type</em></span><span class="special">)&</span> <span class="emphasis"><em>variable-name</em></span> <span class="comment">// Bind by reference with explicit type.</span> 518<span class="keyword">const</span> <span class="identifier">bind</span><span class="special">(</span><span class="emphasis"><em>variable-type</em></span><span class="special">)</span> <span class="emphasis"><em>variable-name</em></span> <span class="comment">// Bind by constant value with explicit type.</span> 519<span class="keyword">const</span> <span class="identifier">bind</span><span class="special">(</span><span class="emphasis"><em>variable-type</em></span><span class="special">)&</span> <span class="emphasis"><em>variable-name</em></span> <span class="comment">// Bind by constant reference with explicit type.</span> 520<span class="identifier">bind</span><span class="special">(</span><span class="emphasis"><em>class-type</em></span><span class="special">*)</span> <span class="identifier">this_</span> <span class="comment">// Bind object `this` with explicit type.</span> 521<span class="keyword">const</span> <span class="identifier">bind</span><span class="special">(</span><span class="emphasis"><em>class-type</em></span><span class="special">*)</span> <span class="identifier">this_</span> <span class="comment">// Bind object `this` by constant with explicit type.</span> 522</pre> 523<p> 524 Note that within the local function body it is always possible to abstract 525 the access to the type of a bound variable using <code class="computeroutput">BOOST_LOCAL_FUNCTION_TYPEOF</code> 526 (even when the bound variable type is explicitly specified in the local function 527 declaration). 528 </p> 529<p> 530 The library also uses <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 531 to determine the local function result type (because this type is specified 532 outside the <code class="computeroutput">BOOST_LOCAL_FUNCTION</code> 533 macro). Thus it is also possible to specify the local function result type 534 as one of the <code class="computeroutput">BOOST_LOCAL_FUNCTION</code> 535 macro parameters prefixing it by <code class="computeroutput"><span class="keyword">return</span></code> 536 so the library will not use <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a> 537 to deduce the result type: 538 </p> 539<pre class="programlisting"><span class="identifier">BOOST_LOCAL_FUNCTION_TYPE</span><span class="special">(</span><span class="keyword">return</span> <code class="literal"><span class="emphasis"><em>result-type</em></span></code><span class="special">,</span> <span class="special">...)</span> 540</pre> 541<p> 542 Note that the result type must be specified only once either before the macro 543 (without the <code class="computeroutput"><span class="keyword">return</span></code> prefix) 544 or as one of the macro parameters (with the <code class="computeroutput"><span class="keyword">return</span></code> 545 prefix). As always, the result type can be <code class="computeroutput"><span class="keyword">void</span></code> 546 to declare a function that returns nothing (so <code class="computeroutput"><span class="keyword">return</span> 547 <span class="keyword">void</span></code> is allowed when the result type 548 is specified as one of the macro parameters). 549 </p> 550<p> 551 The following example specifies all bound variables and result types (see 552 also <a href="../../../test/add_typed.cpp" target="_top"><code class="literal">add_typed.cpp</code></a>): 553 <a href="#ftn.boost_localfunction.advanced_topics.specifying_types__no_boost_typeof_.f0" class="footnote" name="boost_localfunction.advanced_topics.specifying_types__no_boost_typeof_.f0"><sup class="footnote">[22]</sup></a> 554 </p> 555<p> 556</p> 557<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">adder</span> <span class="special">{</span> 558 <span class="identifier">adder</span><span class="special">(</span><span class="keyword">void</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">sum_</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span> 559 560 <span class="keyword">int</span> <span class="identifier">sum</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">>&</span> <span class="identifier">nums</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">int</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="special">{</span> 561 <span class="comment">// Explicitly specify bound variable and return types (no type-of).</span> 562 <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">bind</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&)</span> <span class="identifier">factor</span><span class="special">,</span> 563 <span class="identifier">bind</span><span class="special">(</span><span class="identifier">adder</span><span class="special">*)</span> <span class="identifier">this_</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">,</span> <span class="keyword">return</span> <span class="keyword">int</span><span class="special">)</span> <span class="special">{</span> 564 <span class="keyword">return</span> <span class="identifier">this_</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> 565 <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> 566 567 <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">begin</span><span class="special">(),</span> <span class="identifier">nums</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">add</span><span class="special">);</span> 568 <span class="keyword">return</span> <span class="identifier">sum_</span><span class="special">;</span> 569 <span class="special">}</span> 570 571<span class="keyword">private</span><span class="special">:</span> 572 <span class="keyword">int</span> <span class="identifier">sum_</span><span class="special">;</span> 573<span class="special">};</span> 574</pre> 575<p> 576 </p> 577<p> 578 Unless necessary, it is recommended to not specify the bound variable and 579 result types. Let the library deduce these types so the local function syntax 580 will be more concise and the local function declaration will not have to 581 change if a bound variable type changes (reducing maintenance). 582 </p> 583<div class="note"><table border="0" summary="Note"> 584<tr> 585<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../doc/src/images/note.png"></td> 586<th align="left">Note</th> 587</tr> 588<tr><td align="left" valign="top"><p> 589 When all bound variable and result types are explicitly specified, the 590 library implementation will not use <a href="http://www.boost.org/libs/typeof" target="_top">Boost.Typeof</a>. 591 </p></td></tr> 592</table></div> 593</div> 594<div class="section"> 595<div class="titlepage"><div><div><h3 class="title"> 596<a name="boost_localfunction.advanced_topics.inlining"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.inlining" title="Inlining">Inlining</a> 597</h3></div></div></div> 598<p> 599 Local functions can be declared <a href="http://en.wikipedia.org/wiki/Inline_function" target="_top">inline</a> 600 to increase the chances that the compiler will be able to reduce the run-time 601 of the local function call by inlining the generated assembly code. A local 602 function is declared inline by prefixing its name with the keyword <code class="computeroutput"><span class="keyword">inline</span></code>: 603 </p> 604<pre class="programlisting"><span class="emphasis"><em>result-type</em></span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="emphasis"><em>parameters</em></span><span class="special">)</span> <span class="special">{</span> 605 <span class="special">...</span> <span class="comment">// Body.</span> 606<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="keyword">inline</span> <span class="emphasis"><em>name</em></span><span class="special">)</span> <span class="comment">// Inlining.</span> 607</pre> 608<p> 609 When inlining a local function, note the following: 610 </p> 611<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 612<li class="listitem"> 613 On <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 614 compliant compilers, inline local functions always have a run-time comparable 615 to their equivalent implementation that uses local functors (see the 616 <a class="link" href="alternatives.html" title="Annex: Alternatives">Alternatives</a> 617 section). However, inline local functions have the important limitation 618 that they cannot be assigned to other functors (like <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span></code>) 619 and they cannot be passed as template parameters. 620 </li> 621<li class="listitem"> 622 On <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> 623 compilers, <code class="computeroutput"><span class="keyword">inline</span></code> has no 624 effect because this library will automatically generate code that uses 625 <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> specific 626 features to inline the local function calls whenever possible even if 627 the local function is not declared inline. Furthermore, non <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> 628 local functions can always be passes as template parameters even when 629 they are declared inline. <a href="#ftn.boost_localfunction.advanced_topics.inlining.f0" class="footnote" name="boost_localfunction.advanced_topics.inlining.f0"><sup class="footnote">[23]</sup></a> 630 </li> 631</ul></div> 632<div class="important"><table border="0" summary="Important"> 633<tr> 634<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td> 635<th align="left">Important</th> 636</tr> 637<tr><td align="left" valign="top"><p> 638 It is recommended to not declare a local function inline unless it is strictly 639 necessary for optimizing pure <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 640 compliant code (because in all other cases this library will automatically 641 take advantage of <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> 642 features to optimize the local function calls while always allowing to 643 pass the local function as a template parameter). 644 </p></td></tr> 645</table></div> 646<p> 647 For example, the following local function is declared inline (thus a for-loop 648 needs to be used for portability instead of passing the local function as 649 a template parameter to the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span></code> 650 algorithm, see also <a href="../../../test/add_inline.cpp" target="_top"><code class="literal">add_inline.cpp</code></a>): 651 </p> 652<p> 653</p> 654<pre class="programlisting"><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> 655 656<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">&</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> 657 <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> 658<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="keyword">inline</span> <span class="identifier">add</span><span class="special">)</span> <span class="comment">// Inlining.</span> 659 660<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">v</span><span class="special">(</span><span class="number">100</span><span class="special">);</span> 661<span class="identifier">std</span><span class="special">::</span><span class="identifier">fill</span><span class="special">(</span><span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="number">1</span><span class="special">);</span> 662 663<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"><</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">size</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">v</span><span class="special">[</span><span class="identifier">i</span><span class="special">]);</span> <span class="comment">// Cannot use for_each.</span> 664</pre> 665<p> 666 </p> 667</div> 668<div class="section"> 669<div class="titlepage"><div><div><h3 class="title"> 670<a name="boost_localfunction.advanced_topics.recursion"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.recursion" title="Recursion">Recursion</a> 671</h3></div></div></div> 672<p> 673 Local functions can be declared <a href="http://en.wikipedia.org/wiki/Recursion_(computer_science)#Recursive_procedures" target="_top">recursive</a> 674 so a local function can recursively call itself from its body (as usual with 675 C++ functions). A local function is declared recursive by prefixing its name 676 with the <code class="computeroutput"><span class="identifier">recursive</span></code> "keyword" 677 (thus <code class="computeroutput"><span class="identifier">recursive</span></code> cannot be 678 used as a local function name): 679 </p> 680<pre class="programlisting"><span class="emphasis"><em>result-type</em></span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="emphasis"><em>parameters</em></span><span class="special">)</span> <span class="special">{</span> 681 <span class="special">...</span> <span class="comment">// Body.</span> 682<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">recursive</span> <span class="emphasis"><em>name</em></span><span class="special">)</span> <span class="comment">// Recursive.</span> 683</pre> 684<p> 685 For example, the following local function is used to recursively calculate 686 the factorials of all the numbers in the specified vector (see also <a href="../../../test/factorial.cpp" target="_top"><code class="literal">factorial.cpp</code></a>): 687 </p> 688<p> 689</p> 690<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">calculator</span> <span class="special">{</span> 691 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">results</span><span class="special">;</span> 692 693 <span class="keyword">void</span> <span class="identifier">factorials</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">>&</span> <span class="identifier">nums</span><span class="special">)</span> <span class="special">{</span> 694 <span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="identifier">bind</span> <span class="identifier">this_</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">num</span><span class="special">,</span> 695 <span class="keyword">bool</span> <span class="identifier">recursion</span><span class="special">,</span> <span class="keyword">default</span> <span class="keyword">false</span><span class="special">)</span> <span class="special">{</span> 696 <span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> 697 698 <span class="keyword">if</span><span class="special">(</span><span class="identifier">num</span> <span class="special"><=</span> <span class="number">0</span><span class="special">)</span> <span class="identifier">result</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> 699 <span class="keyword">else</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">num</span> <span class="special">*</span> <span class="identifier">factorial</span><span class="special">(</span><span class="identifier">num</span> <span class="special">-</span> <span class="number">1</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span> <span class="comment">// Recursive call.</span> 700 701 <span class="keyword">if</span><span class="special">(!</span><span class="identifier">recursion</span><span class="special">)</span> <span class="identifier">this_</span><span class="special">-></span><span class="identifier">results</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">result</span><span class="special">);</span> 702 <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span> 703 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">recursive</span> <span class="identifier">factorial</span><span class="special">)</span> <span class="comment">// Recursive.</span> 704 705 <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">begin</span><span class="special">(),</span> <span class="identifier">nums</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">factorial</span><span class="special">);</span> 706 <span class="special">}</span> 707<span class="special">};</span> 708</pre> 709<p> 710 </p> 711<p> 712 Compilers have not been observed to be able to inline recursive local function 713 calls not even when the recursive local function is also declared inline: 714 </p> 715<pre class="programlisting"><span class="special">...</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="keyword">inline</span> <span class="identifier">recursive</span> <span class="identifier">factorial</span><span class="special">)</span> 716</pre> 717<p> 718 Recursive local functions should never be called outside their declaration 719 scope. <a href="#ftn.boost_localfunction.advanced_topics.recursion.f0" class="footnote" name="boost_localfunction.advanced_topics.recursion.f0"><sup class="footnote">[24]</sup></a> 720 </p> 721<div class="warning"><table border="0" summary="Warning"> 722<tr> 723<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td> 724<th align="left">Warning</th> 725</tr> 726<tr><td align="left" valign="top"><p> 727 If a local function is returned from the enclosing function and called 728 in a different scope, the behaviour is undefined (and it will likely result 729 in a run-time error). 730 </p></td></tr> 731</table></div> 732<p> 733 This is not a limitation with respect to <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 734 lambda functions</a> because lambdas can never call themselves recursively 735 (in other words, there is no recursive lambda function that can successfully 736 be called outside its declaration scope because there is no recursive lambda 737 function at all). 738 </p> 739</div> 740<div class="section"> 741<div class="titlepage"><div><div><h3 class="title"> 742<a name="boost_localfunction.advanced_topics.overloading"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.overloading" title="Overloading">Overloading</a> 743</h3></div></div></div> 744<p> 745 Because local functions are functors, it is possible to overload them using 746 the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">overloaded_function</span></code> functor of <a href="http://www.boost.org/libs/functional/overloaded_function" target="_top">Boost.Functional/OverloadedFunction</a> 747 from the <code class="literal">boost/functional/overloaded_function.hpp</code> header 748 (see the <a href="http://www.boost.org/libs/functional/overloaded_function" target="_top">Boost.Functional/OverloadedFunction</a> 749 documentation for details). 750 </p> 751<p> 752 In the following example, the overloaded function object <code class="computeroutput"><span class="identifier">add</span></code> 753 can be called with signatures from either the local function <code class="computeroutput"><span class="identifier">add_s</span></code>, or the local function <code class="computeroutput"><span class="identifier">add_d</span></code>, or the local function <code class="computeroutput"><span class="identifier">add_d</span></code> with its extra default parameter, 754 or the function pointer <code class="computeroutput"><span class="identifier">add_i</span></code> 755 (see also <a href="../../../test/overload.cpp" target="_top"><code class="literal">overload.cpp</code></a>): 756 </p> 757<p> 758</p> 759<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">add_i</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> <span class="special">}</span> 760</pre> 761<p> 762 </p> 763<p> 764</p> 765<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">s</span> <span class="special">=</span> <span class="string">"abc"</span><span class="special">;</span> 766<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span> 767 <span class="keyword">const</span> <span class="identifier">bind</span><span class="special">&</span> <span class="identifier">s</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> 768 <span class="keyword">return</span> <span class="identifier">s</span> <span class="special">+</span> <span class="identifier">x</span><span class="special">;</span> 769<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add_s</span><span class="special">)</span> 770 771<span class="keyword">double</span> <span class="identifier">d</span> <span class="special">=</span> <span class="number">1.23</span><span class="special">;</span> 772<span class="keyword">double</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">d</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">double</span> <span class="identifier">y</span><span class="special">,</span> <span class="keyword">default</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span> 773 <span class="keyword">return</span> <span class="identifier">d</span> <span class="special">+</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> 774<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">add_d</span><span class="special">)</span> 775 776<span class="identifier">boost</span><span class="special">::</span><span class="identifier">overloaded_function</span><span class="special"><</span> 777 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&)</span> 778 <span class="special">,</span> <span class="keyword">double</span> <span class="special">(</span><span class="keyword">double</span><span class="special">)</span> 779 <span class="special">,</span> <span class="keyword">double</span> <span class="special">(</span><span class="keyword">double</span><span class="special">,</span> <span class="keyword">double</span><span class="special">)</span> <span class="comment">// Overload giving default param.</span> 780 <span class="special">,</span> <span class="keyword">int</span> <span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">)</span> 781<span class="special">></span> <span class="identifier">add</span><span class="special">(</span><span class="identifier">add_s</span><span class="special">,</span> <span class="identifier">add_d</span><span class="special">,</span> <span class="identifier">add_d</span><span class="special">,</span> <span class="identifier">add_i</span><span class="special">);</span> <span class="comment">// Overloaded function object.</span> 782 783<span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">add</span><span class="special">(</span><span class="string">"xyz"</span><span class="special">)</span> <span class="special">==</span> <span class="string">"abcxyz"</span><span class="special">);</span> <span class="comment">// Call `add_s`.</span> 784<span class="identifier">BOOST_TEST</span><span class="special">((</span><span class="number">4.44</span> <span class="special">-</span> <span class="identifier">add</span><span class="special">(</span><span class="number">3.21</span><span class="special">))</span> <span class="special"><=</span> <span class="number">0.001</span><span class="special">);</span> <span class="comment">// Call `add_d` (no default).</span> 785<span class="identifier">BOOST_TEST</span><span class="special">((</span><span class="number">44.44</span> <span class="special">-</span> <span class="identifier">add</span><span class="special">(</span><span class="number">3.21</span><span class="special">,</span> <span class="number">40.0</span><span class="special">))</span> <span class="special"><=</span> <span class="number">0.001</span><span class="special">);</span> <span class="comment">// Call `add_d`.</span> 786<span class="identifier">BOOST_TEST</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="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span> <span class="comment">// Call `add_i`.</span> 787</pre> 788<p> 789 </p> 790</div> 791<div class="section"> 792<div class="titlepage"><div><div><h3 class="title"> 793<a name="boost_localfunction.advanced_topics.exception_specifications"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.exception_specifications" title="Exception Specifications">Exception 794 Specifications</a> 795</h3></div></div></div> 796<p> 797 It is possible to program exception specifications for local functions by 798 specifying them after the <code class="computeroutput">BOOST_LOCAL_FUNCTION</code> 799 macro and before the body code block <code class="computeroutput"><span class="special">{</span> 800 <span class="special">...</span> <span class="special">}</span></code>. 801 </p> 802<div class="important"><table border="0" summary="Important"> 803<tr> 804<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../../../doc/src/images/important.png"></td> 805<th align="left">Important</th> 806</tr> 807<tr><td align="left" valign="top"><p> 808 Note that the exception specifications only apply to the body code specified 809 by programmers and they do not apply to the rest of the code automatically 810 generated by the macro expansions to implement local functions. For example, 811 even if the body code is specified to throw no exception using <code class="computeroutput"><span class="keyword">throw</span> <span class="special">()</span> <span class="special">{</span> <span class="special">...</span> <span class="special">}</span></code>, 812 the execution of the library code automatically generated by the macros 813 could still throw (if there is no memory, etc). 814 </p></td></tr> 815</table></div> 816<p> 817 For example (see also <a href="../../../test/add_except.cpp" target="_top"><code class="literal">add_except.cpp</code></a>): 818 </p> 819<p> 820</p> 821<pre class="programlisting"><span class="keyword">double</span> <span class="identifier">sum</span> <span class="special">=</span> <span class="number">0.0</span><span class="special">;</span> 822<span class="keyword">int</span> <span class="identifier">factor</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> 823 824<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">&</span> <span class="identifier">sum</span><span class="special">,</span> 825 <span class="keyword">double</span> <span class="identifier">num</span><span class="special">)</span> <span class="keyword">throw</span><span class="special">()</span> <span class="special">{</span> <span class="comment">// Throw nothing.</span> 826 <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> 827<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> 828 829<span class="identifier">add</span><span class="special">(</span><span class="number">100</span><span class="special">);</span> 830</pre> 831<p> 832 </p> 833</div> 834<div class="section"> 835<div class="titlepage"><div><div><h3 class="title"> 836<a name="boost_localfunction.advanced_topics.storage_classifiers"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.storage_classifiers" title="Storage Classifiers">Storage 837 Classifiers</a> 838</h3></div></div></div> 839<p> 840 Local function parameters support the storage classifiers as usual in <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a>. 841 The <code class="computeroutput"><span class="keyword">auto</span></code> storage classifier 842 is specified as: <a href="#ftn.boost_localfunction.advanced_topics.storage_classifiers.f0" class="footnote" name="boost_localfunction.advanced_topics.storage_classifiers.f0"><sup class="footnote">[25]</sup></a> 843 </p> 844<pre class="programlisting"><span class="keyword">auto</span> <span class="emphasis"><em>parameter-type parameter-name</em></span> 845</pre> 846<p> 847 The <code class="computeroutput"><span class="keyword">register</span></code> storage classifier 848 is specified as: 849 </p> 850<pre class="programlisting"><span class="keyword">register</span> <span class="emphasis"><em>parameter-type parameter-name</em></span> 851</pre> 852</div> 853<div class="section"> 854<div class="titlepage"><div><div><h3 class="title"> 855<a name="boost_localfunction.advanced_topics.same_line_expansions"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.same_line_expansions" title="Same Line Expansions">Same 856 Line Expansions</a> 857</h3></div></div></div> 858<p> 859 In general, it is not possible to expand the <code class="computeroutput">BOOST_LOCAL_FUNCTION</code>, 860 <code class="computeroutput">BOOST_LOCAL_FUNCTION_TPL</code> 861 macros multiple times on the same line. <a href="#ftn.boost_localfunction.advanced_topics.same_line_expansions.f0" class="footnote" name="boost_localfunction.advanced_topics.same_line_expansions.f0"><sup class="footnote">[26]</sup></a> 862 </p> 863<p> 864 Therefore, this library provides additional macros <code class="computeroutput">BOOST_LOCAL_FUNCTION_ID</code> 865 and <code class="computeroutput">BOOST_LOCAL_FUNCTION_ID_TPL</code> 866 which can be expanded multiple times on the same line as long as programmers 867 specify unique identifiers as the macros' first parameters. The unique identifier 868 can be any token (not just numeric) that can be successfully concatenated 869 by the preprocessor (e.g., <code class="computeroutput"><span class="identifier">local_function_number_1_at_line_123</span></code>). 870 <a href="#ftn.boost_localfunction.advanced_topics.same_line_expansions.f1" class="footnote" name="boost_localfunction.advanced_topics.same_line_expansions.f1"><sup class="footnote">[27]</sup></a> 871 </p> 872<p> 873 The <code class="computeroutput">BOOST_LOCAL_FUNCTION_ID</code> 874 and <code class="computeroutput">BOOST_LOCAL_FUNCTION_ID_TPL</code> 875 macros accept local function parameter declaration lists using the exact 876 same syntax as <code class="computeroutput">BOOST_LOCAL_FUNCTION</code>. 877 For example (see also <a href="../../../test/same_line.cpp" target="_top"><code class="literal">same_line.cpp</code></a>): 878 </p> 879<p> 880</p> 881<pre class="programlisting"><span class="preprocessor">#define</span> <span class="identifier">LOCAL_INC_DEC</span><span class="special">(</span><span class="identifier">offset</span><span class="special">)</span> <span class="special">\</span> 882 <span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">inc</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="comment">/* unique ID */</span> <span class="special">\</span> 883 <span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">offset</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span> 884 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span> 885 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">inc</span><span class="special">)</span> <span class="special">\</span> 886 <span class="special">\</span> 887 <span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION_ID</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">dec</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span> 888 <span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">offset</span><span class="special">,</span> <span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span> 889 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">-</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span> 890 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">dec</span><span class="special">)</span> 891 892<span class="preprocessor">#define</span> <span class="identifier">LOCAL_INC_DEC_TPL</span><span class="special">(</span><span class="identifier">offset</span><span class="special">)</span> <span class="special">\</span> 893 <span class="identifier">T</span> <span class="identifier">BOOST_LOCAL_FUNCTION_ID_TPL</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">inc</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span> 894 <span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">offset</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span> 895 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span> 896 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME_TPL</span><span class="special">(</span><span class="identifier">inc</span><span class="special">)</span> <span class="special">\</span> 897 <span class="special">\</span> 898 <span class="identifier">T</span> <span class="identifier">BOOST_LOCAL_FUNCTION_ID_TPL</span><span class="special">(</span><span class="identifier">BOOST_PP_CAT</span><span class="special">(</span><span class="identifier">dec</span><span class="special">,</span> <span class="identifier">__LINE__</span><span class="special">),</span> <span class="special">\</span> 899 <span class="keyword">const</span> <span class="identifier">bind</span> <span class="identifier">offset</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="special">\</span> 900 <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">-</span> <span class="identifier">offset</span><span class="special">;</span> <span class="special">\</span> 901 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME_TPL</span><span class="special">(</span><span class="identifier">dec</span><span class="special">)</span> 902 903<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 904<span class="keyword">void</span> <span class="identifier">f</span><span class="special">(</span><span class="identifier">T</span><span class="special">&</span> <span class="identifier">delta</span><span class="special">)</span> <span class="special">{</span> 905 <span class="identifier">LOCAL_INC_DEC_TPL</span><span class="special">(</span><span class="identifier">delta</span><span class="special">)</span> <span class="comment">// Multiple local functions on same line.</span> 906 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">dec</span><span class="special">(</span><span class="identifier">inc</span><span class="special">(</span><span class="number">123</span><span class="special">))</span> <span class="special">==</span> <span class="number">123</span><span class="special">);</span> 907<span class="special">}</span> 908 909<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> 910 <span class="keyword">int</span> <span class="identifier">delta</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> 911 <span class="identifier">LOCAL_INC_DEC</span><span class="special">(</span><span class="identifier">delta</span><span class="special">)</span> <span class="comment">// Multiple local functions on same line.</span> 912 <span class="identifier">BOOST_TEST</span><span class="special">(</span><span class="identifier">dec</span><span class="special">(</span><span class="identifier">inc</span><span class="special">(</span><span class="number">123</span><span class="special">))</span> <span class="special">==</span> <span class="number">123</span><span class="special">);</span> 913 <span class="identifier">f</span><span class="special">(</span><span class="identifier">delta</span><span class="special">);</span> 914 <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span> 915<span class="special">}</span> 916</pre> 917<p> 918 </p> 919<p> 920 As shown by the example above, the <code class="computeroutput">BOOST_LOCAL_FUNCTION_ID</code> 921 and <code class="computeroutput">BOOST_LOCAL_FUNCTION_ID_TPL</code> 922 macros are especially useful when it is necessary to invoke them multiple 923 times within a user-defined macro (because the preprocessor expands all nested 924 macros on the same line). 925 </p> 926</div> 927<div class="section"> 928<div class="titlepage"><div><div><h3 class="title"> 929<a name="boost_localfunction.advanced_topics.limitations__operators__etc_"></a><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.limitations__operators__etc_" title="Limitations (operators, etc)">Limitations 930 (operators, etc)</a> 931</h3></div></div></div> 932<p> 933 The following table summarizes all C++ function features indicating those 934 features that are not supported by this library for local functions. 935 </p> 936<div class="informaltable"><table class="table"> 937<colgroup> 938<col> 939<col> 940<col> 941</colgroup> 942<thead><tr> 943<th> 944 <p> 945 C++ Function Feature 946 </p> 947 </th> 948<th> 949 <p> 950 Local Function Support 951 </p> 952 </th> 953<th> 954 <p> 955 Comment 956 </p> 957 </th> 958</tr></thead> 959<tbody> 960<tr> 961<td> 962 <p> 963 <code class="computeroutput"><span class="keyword">export</span></code> 964 </p> 965 </td> 966<td> 967 <p> 968 No. 969 </p> 970 </td> 971<td> 972 <p> 973 This is not supported because local functions cannot be templates 974 (plus most C++ compilers do not implement <code class="computeroutput"><span class="keyword">export</span></code> 975 at all). 976 </p> 977 </td> 978</tr> 979<tr> 980<td> 981 <p> 982 <code class="computeroutput"><span class="keyword">template</span><span class="special"><</span></code><code class="literal"><span class="emphasis"><em>template-parameter-list</em></span></code><code class="computeroutput"><span class="special">></span></code> 983 </p> 984 </td> 985<td> 986 <p> 987 No. 988 </p> 989 </td> 990<td> 991 <p> 992 This is not supported because local functions are implemented using 993 local classes and <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 994 local classes cannot be templates. 995 </p> 996 </td> 997</tr> 998<tr> 999<td> 1000 <p> 1001 <code class="computeroutput"><span class="keyword">explicit</span></code> 1002 </p> 1003 </td> 1004<td> 1005 <p> 1006 No. 1007 </p> 1008 </td> 1009<td> 1010 <p> 1011 This is not supported because local functions are not constructors. 1012 </p> 1013 </td> 1014</tr> 1015<tr> 1016<td> 1017 <p> 1018 <code class="computeroutput"><span class="keyword">inline</span></code> 1019 </p> 1020 </td> 1021<td> 1022 <p> 1023 Yes. 1024 </p> 1025 </td> 1026<td> 1027 <p> 1028 Local functions can be specified <code class="computeroutput"><span class="keyword">inline</span></code> 1029 to improve the chances that <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 1030 compilers can optimize the local function call run-time (but <code class="computeroutput"><span class="keyword">inline</span></code> local functions cannot be 1031 passed as template parameters on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 1032 compilers, see the <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced 1033 Topics</a> section). 1034 </p> 1035 </td> 1036</tr> 1037<tr> 1038<td> 1039 <p> 1040 <code class="computeroutput"><span class="keyword">extern</span></code> 1041 </p> 1042 </td> 1043<td> 1044 <p> 1045 No. 1046 </p> 1047 </td> 1048<td> 1049 <p> 1050 This is not supported because local functions are always defined 1051 locally within the enclosing scope and together with their declarations. 1052 </p> 1053 </td> 1054</tr> 1055<tr> 1056<td> 1057 <p> 1058 <code class="computeroutput"><span class="keyword">static</span></code> 1059 </p> 1060 </td> 1061<td> 1062 <p> 1063 No. 1064 </p> 1065 </td> 1066<td> 1067 <p> 1068 This is not supported because local functions are not member functions. 1069 </p> 1070 </td> 1071</tr> 1072<tr> 1073<td> 1074 <p> 1075 <code class="computeroutput"><span class="keyword">virtual</span></code> 1076 </p> 1077 </td> 1078<td> 1079 <p> 1080 No. 1081 </p> 1082 </td> 1083<td> 1084 <p> 1085 This is not supported because local functions are not member functions. 1086 <a href="#ftn.boost_localfunction.advanced_topics.limitations__operators__etc_.f0" class="footnote" name="boost_localfunction.advanced_topics.limitations__operators__etc_.f0"><sup class="footnote">[a]</sup></a> 1087 </p> 1088 </td> 1089</tr> 1090<tr> 1091<td> 1092 <p> 1093 <code class="literal"><span class="emphasis"><em>result-type</em></span></code> 1094 </p> 1095 </td> 1096<td> 1097 <p> 1098 Yes. 1099 </p> 1100 </td> 1101<td> 1102 <p> 1103 This is supported (see the <a class="link" href="tutorial.html" title="Tutorial">Tutorial</a> 1104 section). 1105 </p> 1106 </td> 1107</tr> 1108<tr> 1109<td> 1110 <p> 1111 <code class="literal"><span class="emphasis"><em>function-name</em></span></code> 1112 </p> 1113 </td> 1114<td> 1115 <p> 1116 Yes. 1117 </p> 1118 </td> 1119<td> 1120 <p> 1121 Local functions are named and they can call themselves recursively 1122 but they cannot be operators (see the <a class="link" href="tutorial.html" title="Tutorial">Tutorial</a> 1123 and <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced 1124 Topics</a> sections). 1125 </p> 1126 </td> 1127</tr> 1128<tr> 1129<td> 1130 <p> 1131 <code class="literal"><span class="emphasis"><em>parameter-list</em></span></code> 1132 </p> 1133 </td> 1134<td> 1135 <p> 1136 Yes. 1137 </p> 1138 </td> 1139<td> 1140 <p> 1141 This is supported and it also supports the <code class="computeroutput"><span class="keyword">auto</span></code> 1142 and <code class="computeroutput"><span class="keyword">register</span></code> storage 1143 classifiers, default parameters, and binding of variables in scope 1144 (see the <a class="link" href="tutorial.html" title="Tutorial">Tutorial</a> 1145 and <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced 1146 Topics</a> sections). 1147 </p> 1148 </td> 1149</tr> 1150<tr> 1151<td> 1152 <p> 1153 Trailing <code class="computeroutput"><span class="keyword">const</span></code> qualifier 1154 </p> 1155 </td> 1156<td> 1157 <p> 1158 No. 1159 </p> 1160 </td> 1161<td> 1162 <p> 1163 This is not supported because local functions are not member functions. 1164 </p> 1165 </td> 1166</tr> 1167<tr> 1168<td> 1169 <p> 1170 Trailing <code class="computeroutput"><span class="keyword">volatile</span></code> 1171 qualifier 1172 </p> 1173 </td> 1174<td> 1175 <p> 1176 No. 1177 </p> 1178 </td> 1179<td> 1180 <p> 1181 This is not supported because local functions are not member functions. 1182 </p> 1183 </td> 1184</tr> 1185</tbody> 1186<tbody class="footnotes"><tr><td colspan="3"><div id="ftn.boost_localfunction.advanced_topics.limitations__operators__etc_.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.limitations__operators__etc_.f0" class="para"><sup class="para">[a] </sup></a> 1187 <span class="bold"><strong>Rationale.</strong></span> It would be possible 1188 to make a local function class inherit from another local function 1189 class. However, this "inheritance" feature is not implemented 1190 because it seemed of <a href="http://lists.boost.org/Archives/boost/2010/09/170895.php" target="_top">no 1191 use</a> given that local functions can be bound to one another 1192 thus they can simply call each other directly without recurring 1193 to dynamic binding or base function calls. 1194 </p></div></td></tr></tbody> 1195</table></div> 1196<h5> 1197<a name="boost_localfunction.advanced_topics.limitations__operators__etc_.h0"></a> 1198 <span class="phrase"><a name="boost_localfunction.advanced_topics.limitations__operators__etc_.operators"></a></span><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.limitations__operators__etc_.operators">Operators</a> 1199 </h5> 1200<p> 1201 Local functions cannot be operators. Naming a local function <code class="computeroutput"><span class="keyword">operator</span><span class="special">...</span></code> 1202 will generate a compile-time error. <a href="#ftn.boost_localfunction.advanced_topics.limitations__operators__etc_.f1" class="footnote" name="boost_localfunction.advanced_topics.limitations__operators__etc_.f1"><sup class="footnote">[28]</sup></a> 1203 </p> 1204<p> 1205 For example, the following code does not compile (see also <a href="../../../test/operator_error.cpp" target="_top"><code class="literal">operator_error.cpp</code></a>): 1206 </p> 1207<p> 1208</p> 1209<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">point</span><span class="special">&</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">point</span><span class="special">&</span> <span class="identifier">q</span><span class="special">)</span> <span class="special">{</span> 1210 <span class="keyword">return</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">x</span> <span class="special">==</span> <span class="identifier">q</span><span class="special">.</span><span class="identifier">x</span> <span class="special">&&</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">y</span> <span class="special">==</span> <span class="identifier">q</span><span class="special">.</span><span class="identifier">y</span><span class="special">;</span> 1211<span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="keyword">operator</span><span class="special">==)</span> <span class="comment">// Error: Cannot use `operator...`.</span> 1212</pre> 1213<p> 1214 </p> 1215<h5> 1216<a name="boost_localfunction.advanced_topics.limitations__operators__etc_.h1"></a> 1217 <span class="phrase"><a name="boost_localfunction.advanced_topics.limitations__operators__etc_.goto"></a></span><a class="link" href="advanced_topics.html#boost_localfunction.advanced_topics.limitations__operators__etc_.goto">Goto</a> 1218 </h5> 1219<p> 1220 It is possible to jump with a <code class="computeroutput"><span class="keyword">goto</span></code> 1221 within the local function body. For example, the following compiles (see 1222 also <a href="../../../test/goto.cpp" target="_top"><code class="literal">goto.cpp</code></a>): 1223 </p> 1224<p> 1225</p> 1226<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">error</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> 1227 <span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">z</span><span class="special">)</span> <span class="special">{</span> 1228 <span class="keyword">if</span><span class="special">(</span><span class="identifier">z</span> <span class="special">></span> <span class="number">0</span><span class="special">)</span> <span class="keyword">goto</span> <span class="identifier">success</span><span class="special">;</span> <span class="comment">// OK: Can jump within local function.</span> 1229 <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> 1230 <span class="identifier">success</span><span class="special">:</span> 1231 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 1232 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">validate</span><span class="special">)</span> 1233 1234 <span class="keyword">return</span> <span class="identifier">validate</span><span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">);</span> 1235<span class="special">}</span> 1236</pre> 1237<p> 1238 </p> 1239<p> 1240 However, it is not possible to jump with a <code class="computeroutput"><span class="keyword">goto</span></code> 1241 from within the local function body to to a label defined in the enclosing 1242 scope. For example, the following does not compile (see also <a href="../../../test/goto_error.cpp" target="_top"><code class="literal">goto_error.cpp</code></a>): 1243 </p> 1244<p> 1245</p> 1246<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">error</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> 1247 <span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">int</span> <span class="identifier">z</span><span class="special">)</span> <span class="special">{</span> 1248 <span class="keyword">if</span><span class="special">(</span><span class="identifier">z</span> <span class="special"><=</span> <span class="number">0</span><span class="special">)</span> <span class="keyword">goto</span> <span class="identifier">failure</span><span class="special">;</span> <span class="comment">// Error: Cannot jump to enclosing scope.</span> 1249 <span class="keyword">else</span> <span class="keyword">goto</span> <span class="identifier">success</span><span class="special">;</span> <span class="comment">// OK: Can jump within local function.</span> 1250 <span class="identifier">success</span><span class="special">:</span> 1251 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 1252 <span class="special">}</span> <span class="identifier">BOOST_LOCAL_FUNCTION_NAME</span><span class="special">(</span><span class="identifier">validate</span><span class="special">)</span> 1253 1254 <span class="keyword">return</span> <span class="identifier">validate</span><span class="special">(</span><span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">);</span> 1255<span class="identifier">failure</span><span class="special">:</span> 1256 <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> 1257<span class="special">}</span> 1258</pre> 1259<p> 1260 </p> 1261</div> 1262<div class="footnotes"> 1263<br><hr style="width:100; text-align:left;margin-left: 0"> 1264<div id="ftn.boost_localfunction.advanced_topics.default_parameters.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.default_parameters.f0" class="para"><sup class="para">[17] </sup></a> 1265 <span class="bold"><strong>Rationale.</strong></span> The assignment symbol <code class="computeroutput"><span class="special">=</span></code> cannot be used to specify default parameter 1266 values because default values are not part of the parameter type so they 1267 cannot be handled using template meta-programming. Default parameter values 1268 need to be separated from the rest of the parameter declaration using the 1269 preprocessor. Specifically, this library needs to use preprocessor meta-programming 1270 to remove default values when constructing the local function type and 1271 also to count the number of default values to provide the correct set of 1272 call operators for the local functor. Therefore, the symbol <code class="computeroutput"><span class="special">=</span></code> cannot be used because it cannot be handled 1273 by preprocessor meta-programming (non-alphanumeric symbols cannot be detected 1274 by preprocessor meta-programming because they cannot be concatenated by 1275 the preprocessor). 1276 </p></div> 1277<div id="ftn.boost_localfunction.advanced_topics.default_parameters.f1" class="footnote"><p><a href="#boost_localfunction.advanced_topics.default_parameters.f1" class="para"><sup class="para">[18] </sup></a> 1278 The authors do not personally find the use of the <code class="computeroutput"><span class="identifier">WITH_DEFAULT</span></code> 1279 macro more readable and they prefer to use the <code class="computeroutput"><span class="keyword">default</span></code> 1280 keyword directly. Furthermore, <code class="computeroutput"><span class="identifier">WITH_DEFAULT</span></code> 1281 needs to be defined differently for compilers without variadic macros 1282 <code class="computeroutput"><span class="preprocessor">#define</span> <span class="identifier">WITH_DEFAULT</span> 1283 <span class="special">(</span><span class="keyword">default</span><span class="special">)</span></code> so it can only be defined by programmers 1284 based on the syntax they decide to use (see the <a class="link" href="no_variadic_macros.html" title="Annex: No Variadic Macros">No 1285 Variadic Macros</a> section). 1286 </p></div> 1287<div id="ftn.boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f0" class="para"><sup class="para">[19] </sup></a> 1288 <span class="bold"><strong>Rationale.</strong></span> This limitation is because 1289 this library uses preprocessor token concatenation <code class="literal">##</code> 1290 to inspect the macro parameters (to distinguish between function parameters, 1291 bound variables, etc) and the C++ preprocessor does not allow to concatenate 1292 non-alphanumeric tokens. 1293 </p></div> 1294<div id="ftn.boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f1" class="footnote"><p><a href="#boost_localfunction.advanced_topics.commas_and_symbols_in_macros.f1" class="para"><sup class="para">[20] </sup></a> 1295 The preprocessor always interprets unwrapped commas as separating macro 1296 parameters. Thus in this case the comma will indicate to the preprocessor 1297 that the first macro parameter is <code class="computeroutput"><span class="keyword">const</span> 1298 <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tring</span></code>, the second macro parameter is 1299 <code class="computeroutput"><span class="identifier">size_t</span><span class="special">>&</span> 1300 <span class="identifier">m</span></code>, etc instead of passing <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="identifier">size_t</span><span class="special">>&</span> <span class="identifier">m</span></code> 1301 as a single macro parameter. 1302 </p></div> 1303<div id="ftn.boost_localfunction.advanced_topics.accessing_types__concepts__etc_.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.accessing_types__concepts__etc_.f0" class="para"><sup class="para">[21] </sup></a> 1304 <span class="bold"><strong>Rationale.</strong></span> The type names <code class="computeroutput"><span class="identifier">result_type</span></code> and <code class="computeroutput"><span class="identifier">arg</span></code><code class="literal"><span class="emphasis"><em>N</em></span></code><code class="computeroutput"><span class="identifier">_type</span></code> follow the <a href="http://www.boost.org/libs/type_traits" target="_top">Boost.TypeTraits</a> 1305 naming conventions for function traits. 1306 </p></div> 1307<div id="ftn.boost_localfunction.advanced_topics.specifying_types__no_boost_typeof_.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.specifying_types__no_boost_typeof_.f0" class="para"><sup class="para">[22] </sup></a> 1308 In the examples of this documentation, bound variables, function parameters, 1309 and the result type are specified in this order because this is the order 1310 used by <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 1311 lambda functions</a>. However, the library accepts bound variables, 1312 function parameters, and the result type in any order. 1313 </p></div> 1314<div id="ftn.boost_localfunction.advanced_topics.inlining.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.inlining.f0" class="para"><sup class="para">[23] </sup></a> 1315 <span class="bold"><strong>Rationale.</strong></span> This library uses an indirect 1316 function call via a function pointer in order to pass the local function 1317 as a template parameter (see the <a class="link" href="implementation.html" title="Annex: Implementation">Implementation</a> 1318 section). No compiler has yet been observed to be able to inline function 1319 calls when they use such indirect function pointer calls. Therefore, 1320 inline local functions do not use such indirect function pointer call 1321 (so they are more likely to be optimized) but because of that they 1322 cannot be passed as template parameters. The indirect function pointer 1323 call is needed on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 1324 but it is not needed on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> 1325 (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a> 1326 and <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s 1327 <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>) 1328 thus this library automatically generates local function calls that 1329 can be inline on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> 1330 compilers (even when the local function is not declared inline). 1331 </p></div> 1332<div id="ftn.boost_localfunction.advanced_topics.recursion.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.recursion.f0" class="para"><sup class="para">[24] </sup></a> 1333 <span class="bold"><strong>Rationale.</strong></span> This limitation comes from 1334 the fact that the global functor used to pass the local function as a template 1335 parameter (and eventually returned outside the declarations scope) does 1336 not know the local function name so the local function name used for recursive 1337 call cannot be set in the global functor. This limitation together with 1338 preventing the possibility for inlining are the reasons why local functions 1339 are not recursive unless programmers explicitly declare them <code class="computeroutput"><span class="identifier">recursive</span></code>. 1340 </p></div> 1341<div id="ftn.boost_localfunction.advanced_topics.storage_classifiers.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.storage_classifiers.f0" class="para"><sup class="para">[25] </sup></a> 1342 The <code class="computeroutput"><span class="keyword">auto</span></code> storage classifier 1343 is part of the <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 1344 standard and therefore supported by this library. However, the meaning 1345 and usage of the <code class="computeroutput"><span class="keyword">auto</span></code> keyword 1346 changed in <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>. 1347 Therefore, use the <code class="computeroutput"><span class="keyword">auto</span></code> storage 1348 classifier with the usual care in order to avoid writing <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> 1349 code that might not work on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>. 1350 </p></div> 1351<div id="ftn.boost_localfunction.advanced_topics.same_line_expansions.f0" class="footnote"><p><a href="#boost_localfunction.advanced_topics.same_line_expansions.f0" class="para"><sup class="para">[26] </sup></a> 1352 <span class="bold"><strong>Rationale.</strong></span> The <code class="computeroutput">BOOST_LOCAL_FUNCTION</code> 1353 and <code class="computeroutput">BOOST_LOCAL_FUNCTION_TPL</code> 1354 macros internally use <code class="computeroutput"><span class="identifier">__LINE__</span></code> 1355 to generate unique identifiers. Therefore, if these macros are expanded 1356 more than on time on the same line, the generated identifiers will no longer 1357 be unique and the code will not compile. (This restriction does not apply 1358 to MSVC and other compilers that provide the non-standard <code class="computeroutput"><span class="identifier">__COUNTER__</span></code> macro.) Note that the <code class="computeroutput">BOOST_LOCAL_FUNCTION_NAME</code> macro 1359 can always be expanded multiple times on the same line because the unique 1360 local function name (and not <code class="computeroutput"><span class="identifier">__LINE__</span></code>) 1361 is used by this macro to generate unique identifiers (so there is no need 1362 for a <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION_NAME_ID</span></code> 1363 macro). 1364 </p></div> 1365<div id="ftn.boost_localfunction.advanced_topics.same_line_expansions.f1" class="footnote"><p><a href="#boost_localfunction.advanced_topics.same_line_expansions.f1" class="para"><sup class="para">[27] </sup></a> 1366 Because there are restrictions on the set of tokens that the preprocessor 1367 can concatenate and because not all compilers correctly implement these 1368 restrictions, it is in general recommended to specify unique identifiers 1369 as a combination of alphanumeric tokens. 1370 </p></div> 1371<div id="ftn.boost_localfunction.advanced_topics.limitations__operators__etc_.f1" class="footnote"><p><a href="#boost_localfunction.advanced_topics.limitations__operators__etc_.f1" class="para"><sup class="para">[28] </sup></a> 1372 <span class="bold"><strong>Rationale.</strong></span> This is the because a local 1373 function name must be a valid local variable name (the local variable used 1374 to hold the local functor) and operators cannot be used as local variable 1375 names. 1376 </p></div> 1377</div> 1378</div> 1379<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 1380<td align="left"></td> 1381<td align="right"><div class="copyright-footer">Copyright © 2009-2012 Lorenzo 1382 Caminiti<p> 1383 Distributed under the Boost Software License, Version 1.0 (see accompanying 1384 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>) 1385 </p> 1386</div></td> 1387</tr></table> 1388<hr> 1389<div class="spirit-nav"> 1390<a accesskey="p" href="tutorial.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="examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a> 1391</div> 1392</body> 1393</html> 1394