]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <html> |
2 | <head> | |
3 | <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> | |
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.78.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"><a class="link" href="../BOOST_LOCAL_FUNCTION_TPL.html" title="Macro BOOST_LOCAL_FUNCTION_TPL">BOOST_LOCAL_FUNCTION_TPL</a></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"><a class="link" href="../BOOST_LOCAL_FUNCTION_TYPEOF.html" title="Macro BOOST_LOCAL_FUNCTION_TYPEOF">BOOST_LOCAL_FUNCTION_TYPEOF</a></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"><a class="link" href="../BOOST_LOCAL_FUNCTION_TYPEOF.html" title="Macro BOOST_LOCAL_FUNCTION_TYPEOF">BOOST_LOCAL_FUNCTION_TYPEOF</a></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"><a class="link" href="../BOOST_LOCAL_FUNCTION_TYPEOF.html" title="Macro BOOST_LOCAL_FUNCTION_TYPEOF">BOOST_LOCAL_FUNCTION_TYPEOF</a></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"><a class="link" href="../BOOST_LOCAL_FUNCTION_TYPEOF.html" title="Macro BOOST_LOCAL_FUNCTION_TYPEOF">BOOST_LOCAL_FUNCTION_TYPEOF</a></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"><a class="link" href="../BOOST_LOCAL_FUNCTION.html" title="Macro BOOST_LOCAL_FUNCTION">BOOST_LOCAL_FUNCTION</a></code> | |
533 | macro). Thus it is also possible to specify the local function result type | |
534 | as one of the <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION.html" title="Macro BOOST_LOCAL_FUNCTION">BOOST_LOCAL_FUNCTION</a></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"><a class="link" href="../BOOST_LOCAL_FUNCTION.html" title="Macro BOOST_LOCAL_FUNCTION">BOOST_LOCAL_FUNCTION</a></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 | <p> | |
853 | For example (see also <a href="../../../test/add_classifiers.cpp" target="_top"><code class="literal">add_classifiers.cpp</code></a>): | |
854 | </p> | |
855 | <p> | |
856 | </p> | |
857 | <pre class="programlisting"><span class="keyword">int</span> <span class="identifier">BOOST_LOCAL_FUNCTION</span><span class="special">(</span><span class="keyword">auto</span> <span class="keyword">int</span> <span class="identifier">x</span><span class="special">,</span> <span class="keyword">register</span> <span class="keyword">int</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">{</span> <span class="comment">// Classifiers.</span> | |
858 | <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">+</span> <span class="identifier">y</span><span class="special">;</span> | |
859 | <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> | |
860 | </pre> | |
861 | <p> | |
862 | </p> | |
863 | </div> | |
864 | <div class="section"> | |
865 | <div class="titlepage"><div><div><h3 class="title"> | |
866 | <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 | |
867 | Line Expansions</a> | |
868 | </h3></div></div></div> | |
869 | <p> | |
870 | In general, it is not possible to expand the <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION.html" title="Macro BOOST_LOCAL_FUNCTION">BOOST_LOCAL_FUNCTION</a></code>, | |
871 | <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_TPL.html" title="Macro BOOST_LOCAL_FUNCTION_TPL">BOOST_LOCAL_FUNCTION_TPL</a></code> | |
872 | 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> | |
873 | </p> | |
874 | <p> | |
875 | Therefore, this library provides additional macros <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_ID.html" title="Macro BOOST_LOCAL_FUNCTION_ID">BOOST_LOCAL_FUNCTION_ID</a></code> | |
876 | and <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_ID_TPL.html" title="Macro BOOST_LOCAL_FUNCTION_ID_TPL">BOOST_LOCAL_FUNCTION_ID_TPL</a></code> | |
877 | which can be expanded multiple times on the same line as long as programmers | |
878 | specify unique identifiers as the macros' first parameters. The unique identifier | |
879 | can be any token (not just numeric) that can be successfully concatenated | |
880 | by the preprocessor (e.g., <code class="computeroutput"><span class="identifier">local_function_number_1_at_line_123</span></code>). | |
881 | <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> | |
882 | </p> | |
883 | <p> | |
884 | The <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_ID.html" title="Macro BOOST_LOCAL_FUNCTION_ID">BOOST_LOCAL_FUNCTION_ID</a></code> | |
885 | and <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_ID_TPL.html" title="Macro BOOST_LOCAL_FUNCTION_ID_TPL">BOOST_LOCAL_FUNCTION_ID_TPL</a></code> | |
886 | macros accept local function parameter declaration lists using the exact | |
887 | same syntax as <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION.html" title="Macro BOOST_LOCAL_FUNCTION">BOOST_LOCAL_FUNCTION</a></code>. | |
888 | For example (see also <a href="../../../test/same_line.cpp" target="_top"><code class="literal">same_line.cpp</code></a>): | |
889 | </p> | |
890 | <p> | |
891 | </p> | |
892 | <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> | |
893 | <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> | |
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="keyword">int</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</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="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> | |
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="keyword">int</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</span><span class="special">(</span><span class="identifier">dec</span><span class="special">)</span> | |
902 | ||
903 | <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> | |
904 | <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> | |
905 | <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> | |
906 | <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> | |
907 | <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> | |
908 | <span class="special">\</span> | |
909 | <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> | |
910 | <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> | |
911 | <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> | |
912 | <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> | |
913 | ||
914 | <span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> | |
915 | <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> | |
916 | <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> | |
917 | <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> | |
918 | <span class="special">}</span> | |
919 | ||
920 | <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> | |
921 | <span class="keyword">int</span> <span class="identifier">delta</span> <span class="special">=</span> <span class="number">10</span><span class="special">;</span> | |
922 | <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> | |
923 | <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> | |
924 | <span class="identifier">f</span><span class="special">(</span><span class="identifier">delta</span><span class="special">);</span> | |
925 | <span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">report_errors</span><span class="special">();</span> | |
926 | <span class="special">}</span> | |
927 | </pre> | |
928 | <p> | |
929 | </p> | |
930 | <p> | |
931 | As shown by the example above, the <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_ID.html" title="Macro BOOST_LOCAL_FUNCTION_ID">BOOST_LOCAL_FUNCTION_ID</a></code> | |
932 | and <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_ID_TPL.html" title="Macro BOOST_LOCAL_FUNCTION_ID_TPL">BOOST_LOCAL_FUNCTION_ID_TPL</a></code> | |
933 | macros are especially useful when it is necessary to invoke them multiple | |
934 | times within a user-defined macro (because the preprocessor expands all nested | |
935 | macros on the same line). | |
936 | </p> | |
937 | </div> | |
938 | <div class="section"> | |
939 | <div class="titlepage"><div><div><h3 class="title"> | |
940 | <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 | |
941 | (operators, etc)</a> | |
942 | </h3></div></div></div> | |
943 | <p> | |
944 | The following table summarizes all C++ function features indicating those | |
945 | features that are not supported by this library for local functions. | |
946 | </p> | |
947 | <div class="informaltable"><table class="table"> | |
948 | <colgroup> | |
949 | <col> | |
950 | <col> | |
951 | <col> | |
952 | </colgroup> | |
953 | <thead><tr> | |
954 | <th> | |
955 | <p> | |
956 | C++ Function Feature | |
957 | </p> | |
958 | </th> | |
959 | <th> | |
960 | <p> | |
961 | Local Function Support | |
962 | </p> | |
963 | </th> | |
964 | <th> | |
965 | <p> | |
966 | Comment | |
967 | </p> | |
968 | </th> | |
969 | </tr></thead> | |
970 | <tbody> | |
971 | <tr> | |
972 | <td> | |
973 | <p> | |
974 | <code class="computeroutput"><span class="keyword">export</span></code> | |
975 | </p> | |
976 | </td> | |
977 | <td> | |
978 | <p> | |
979 | No. | |
980 | </p> | |
981 | </td> | |
982 | <td> | |
983 | <p> | |
984 | This is not supported because local functions cannot be templates | |
985 | (plus most C++ compilers do not implement <code class="computeroutput"><span class="keyword">export</span></code> | |
986 | at all). | |
987 | </p> | |
988 | </td> | |
989 | </tr> | |
990 | <tr> | |
991 | <td> | |
992 | <p> | |
993 | <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> | |
994 | </p> | |
995 | </td> | |
996 | <td> | |
997 | <p> | |
998 | No. | |
999 | </p> | |
1000 | </td> | |
1001 | <td> | |
1002 | <p> | |
1003 | This is not supported because local functions are implemented using | |
1004 | local classes and <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> | |
1005 | local classes cannot be templates. | |
1006 | </p> | |
1007 | </td> | |
1008 | </tr> | |
1009 | <tr> | |
1010 | <td> | |
1011 | <p> | |
1012 | <code class="computeroutput"><span class="keyword">explicit</span></code> | |
1013 | </p> | |
1014 | </td> | |
1015 | <td> | |
1016 | <p> | |
1017 | No. | |
1018 | </p> | |
1019 | </td> | |
1020 | <td> | |
1021 | <p> | |
1022 | This is not supported because local functions are not constructors. | |
1023 | </p> | |
1024 | </td> | |
1025 | </tr> | |
1026 | <tr> | |
1027 | <td> | |
1028 | <p> | |
1029 | <code class="computeroutput"><span class="keyword">inline</span></code> | |
1030 | </p> | |
1031 | </td> | |
1032 | <td> | |
1033 | <p> | |
1034 | Yes. | |
1035 | </p> | |
1036 | </td> | |
1037 | <td> | |
1038 | <p> | |
1039 | Local functions can be specified <code class="computeroutput"><span class="keyword">inline</span></code> | |
1040 | to improve the chances that <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> | |
1041 | compilers can optimize the local function call run-time (but <code class="computeroutput"><span class="keyword">inline</span></code> local functions cannot be | |
1042 | passed as template parameters on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> | |
1043 | compilers, see the <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced | |
1044 | Topics</a> section). | |
1045 | </p> | |
1046 | </td> | |
1047 | </tr> | |
1048 | <tr> | |
1049 | <td> | |
1050 | <p> | |
1051 | <code class="computeroutput"><span class="keyword">extern</span></code> | |
1052 | </p> | |
1053 | </td> | |
1054 | <td> | |
1055 | <p> | |
1056 | No. | |
1057 | </p> | |
1058 | </td> | |
1059 | <td> | |
1060 | <p> | |
1061 | This is not supported because local functions are always defined | |
1062 | locally within the enclosing scope and together with their declarations. | |
1063 | </p> | |
1064 | </td> | |
1065 | </tr> | |
1066 | <tr> | |
1067 | <td> | |
1068 | <p> | |
1069 | <code class="computeroutput"><span class="keyword">static</span></code> | |
1070 | </p> | |
1071 | </td> | |
1072 | <td> | |
1073 | <p> | |
1074 | No. | |
1075 | </p> | |
1076 | </td> | |
1077 | <td> | |
1078 | <p> | |
1079 | This is not supported because local functions are not member functions. | |
1080 | </p> | |
1081 | </td> | |
1082 | </tr> | |
1083 | <tr> | |
1084 | <td> | |
1085 | <p> | |
1086 | <code class="computeroutput"><span class="keyword">virtual</span></code> | |
1087 | </p> | |
1088 | </td> | |
1089 | <td> | |
1090 | <p> | |
1091 | No. | |
1092 | </p> | |
1093 | </td> | |
1094 | <td> | |
1095 | <p> | |
1096 | This is not supported because local functions are not member functions. | |
1097 | <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> | |
1098 | </p> | |
1099 | </td> | |
1100 | </tr> | |
1101 | <tr> | |
1102 | <td> | |
1103 | <p> | |
1104 | <code class="literal"><span class="emphasis"><em>result-type</em></span></code> | |
1105 | </p> | |
1106 | </td> | |
1107 | <td> | |
1108 | <p> | |
1109 | Yes. | |
1110 | </p> | |
1111 | </td> | |
1112 | <td> | |
1113 | <p> | |
1114 | This is supported (see the <a class="link" href="tutorial.html" title="Tutorial">Tutorial</a> | |
1115 | section). | |
1116 | </p> | |
1117 | </td> | |
1118 | </tr> | |
1119 | <tr> | |
1120 | <td> | |
1121 | <p> | |
1122 | <code class="literal"><span class="emphasis"><em>function-name</em></span></code> | |
1123 | </p> | |
1124 | </td> | |
1125 | <td> | |
1126 | <p> | |
1127 | Yes. | |
1128 | </p> | |
1129 | </td> | |
1130 | <td> | |
1131 | <p> | |
1132 | Local functions are named and they can call themselves recursively | |
1133 | but they cannot be operators (see the <a class="link" href="tutorial.html" title="Tutorial">Tutorial</a> | |
1134 | and <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced | |
1135 | Topics</a> sections). | |
1136 | </p> | |
1137 | </td> | |
1138 | </tr> | |
1139 | <tr> | |
1140 | <td> | |
1141 | <p> | |
1142 | <code class="literal"><span class="emphasis"><em>parameter-list</em></span></code> | |
1143 | </p> | |
1144 | </td> | |
1145 | <td> | |
1146 | <p> | |
1147 | Yes. | |
1148 | </p> | |
1149 | </td> | |
1150 | <td> | |
1151 | <p> | |
1152 | This is supported and it also supports the <code class="computeroutput"><span class="keyword">auto</span></code> | |
1153 | and <code class="computeroutput"><span class="keyword">register</span></code> storage | |
1154 | classifiers, default parameters, and binding of variables in scope | |
1155 | (see the <a class="link" href="tutorial.html" title="Tutorial">Tutorial</a> | |
1156 | and <a class="link" href="advanced_topics.html" title="Advanced Topics">Advanced | |
1157 | Topics</a> sections). | |
1158 | </p> | |
1159 | </td> | |
1160 | </tr> | |
1161 | <tr> | |
1162 | <td> | |
1163 | <p> | |
1164 | Trailing <code class="computeroutput"><span class="keyword">const</span></code> qualifier | |
1165 | </p> | |
1166 | </td> | |
1167 | <td> | |
1168 | <p> | |
1169 | No. | |
1170 | </p> | |
1171 | </td> | |
1172 | <td> | |
1173 | <p> | |
1174 | This is not supported because local functions are not member functions. | |
1175 | </p> | |
1176 | </td> | |
1177 | </tr> | |
1178 | <tr> | |
1179 | <td> | |
1180 | <p> | |
1181 | Trailing <code class="computeroutput"><span class="keyword">volatile</span></code> | |
1182 | qualifier | |
1183 | </p> | |
1184 | </td> | |
1185 | <td> | |
1186 | <p> | |
1187 | No. | |
1188 | </p> | |
1189 | </td> | |
1190 | <td> | |
1191 | <p> | |
1192 | This is not supported because local functions are not member functions. | |
1193 | </p> | |
1194 | </td> | |
1195 | </tr> | |
1196 | </tbody> | |
1197 | <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> | |
1198 | <span class="bold"><strong>Rationale.</strong></span> It would be possible | |
1199 | to make a local function class inherit from another local function | |
1200 | class. However, this "inheritance" feature is not implemented | |
1201 | because it seemed of <a href="http://lists.boost.org/Archives/boost/2010/09/170895.php" target="_top">no | |
1202 | use</a> given that local functions can be bound to one another | |
1203 | thus they can simply call each other directly without recurring | |
1204 | to dynamic binding or base function calls. | |
1205 | </p></div></td></tr></tbody> | |
1206 | </table></div> | |
1207 | <h5> | |
1208 | <a name="boost_localfunction.advanced_topics.limitations__operators__etc_.h0"></a> | |
1209 | <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> | |
1210 | </h5> | |
1211 | <p> | |
1212 | Local functions cannot be operators. Naming a local function <code class="computeroutput"><span class="keyword">operator</span><span class="special">...</span></code> | |
1213 | 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> | |
1214 | </p> | |
1215 | <p> | |
1216 | 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>): | |
1217 | </p> | |
1218 | <p> | |
1219 | </p> | |
1220 | <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> | |
1221 | <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> | |
1222 | <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> | |
1223 | </pre> | |
1224 | <p> | |
1225 | </p> | |
1226 | <h5> | |
1227 | <a name="boost_localfunction.advanced_topics.limitations__operators__etc_.h1"></a> | |
1228 | <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> | |
1229 | </h5> | |
1230 | <p> | |
1231 | It is possible to jump with a <code class="computeroutput"><span class="keyword">goto</span></code> | |
1232 | within the local function body. For example, the following compiles (see | |
1233 | also <a href="../../../test/goto.cpp" target="_top"><code class="literal">goto.cpp</code></a>): | |
1234 | </p> | |
1235 | <p> | |
1236 | </p> | |
1237 | <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> | |
1238 | <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> | |
1239 | <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> | |
1240 | <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> | |
1241 | <span class="identifier">success</span><span class="special">:</span> | |
1242 | <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> | |
1243 | <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> | |
1244 | ||
1245 | <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> | |
1246 | <span class="special">}</span> | |
1247 | </pre> | |
1248 | <p> | |
1249 | </p> | |
1250 | <p> | |
1251 | However, it is not possible to jump with a <code class="computeroutput"><span class="keyword">goto</span></code> | |
1252 | from within the local function body to to a label defined in the enclosing | |
1253 | 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>): | |
1254 | </p> | |
1255 | <p> | |
1256 | </p> | |
1257 | <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> | |
1258 | <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> | |
1259 | <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> | |
1260 | <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> | |
1261 | <span class="identifier">success</span><span class="special">:</span> | |
1262 | <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> | |
1263 | <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> | |
1264 | ||
1265 | <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> | |
1266 | <span class="identifier">failure</span><span class="special">:</span> | |
1267 | <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> | |
1268 | <span class="special">}</span> | |
1269 | </pre> | |
1270 | <p> | |
1271 | </p> | |
1272 | </div> | |
1273 | <div class="footnotes"> | |
1274 | <br><hr style="width:100; text-align:left;margin-left: 0"> | |
1275 | <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> | |
1276 | <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 | |
1277 | values because default values are not part of the parameter type so they | |
1278 | cannot be handled using template meta-programming. Default parameter values | |
1279 | need to be separated from the rest of the parameter declaration using the | |
1280 | preprocessor. Specifically, this library needs to use preprocessor meta-programming | |
1281 | to remove default values when constructing the local function type and | |
1282 | also to count the number of default values to provide the correct set of | |
1283 | 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 | |
1284 | by preprocessor meta-programming (non-alphanumeric symbols cannot be detected | |
1285 | by preprocessor meta-programming because they cannot be concatenated by | |
1286 | the preprocessor). | |
1287 | </p></div> | |
1288 | <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> | |
1289 | The authors do not personally find the use of the <code class="computeroutput"><span class="identifier">WITH_DEFAULT</span></code> | |
1290 | macro more readable and they prefer to use the <code class="computeroutput"><span class="keyword">default</span></code> | |
1291 | keyword directly. Furthermore, <code class="computeroutput"><span class="identifier">WITH_DEFAULT</span></code> | |
1292 | needs to be defined differently for compilers without variadic macros | |
1293 | <code class="computeroutput"><span class="preprocessor">#define</span> <span class="identifier">WITH_DEFAULT</span> | |
1294 | <span class="special">(</span><span class="keyword">default</span><span class="special">)</span></code> so it can only be defined by programmers | |
1295 | based on the syntax they decide to use (see the <a class="link" href="no_variadic_macros.html" title="Annex: No Variadic Macros">No | |
1296 | Variadic Macros</a> section). | |
1297 | </p></div> | |
1298 | <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> | |
1299 | <span class="bold"><strong>Rationale.</strong></span> This limitation is because | |
1300 | this library uses preprocessor token concatenation <code class="literal">##</code> | |
1301 | to inspect the macro parameters (to distinguish between function parameters, | |
1302 | bound variables, etc) and the C++ preprocessor does not allow to concatenate | |
1303 | non-alphanumeric tokens. | |
1304 | </p></div> | |
1305 | <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> | |
1306 | The preprocessor always interprets unwrapped commas as separating macro | |
1307 | parameters. Thus in this case the comma will indicate to the preprocessor | |
1308 | that the first macro parameter is <code class="computeroutput"><span class="keyword">const</span> | |
1309 | <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 | |
1310 | <code class="computeroutput"><span class="identifier">size_t</span><span class="special">>&</span> | |
1311 | <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> | |
1312 | as a single macro parameter. | |
1313 | </p></div> | |
1314 | <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> | |
1315 | <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> | |
1316 | naming conventions for function traits. | |
1317 | </p></div> | |
1318 | <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> | |
1319 | In the examples of this documentation, bound variables, function parameters, | |
1320 | and the result type are specified in this order because this is the order | |
1321 | used by <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions" target="_top">C++11 | |
1322 | lambda functions</a>. However, the library accepts bound variables, | |
1323 | function parameters, and the result type in any order. | |
1324 | </p></div> | |
1325 | <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> | |
1326 | <span class="bold"><strong>Rationale.</strong></span> This library uses an indirect | |
1327 | function call via a function pointer in order to pass the local function | |
1328 | as a template parameter (see the <a class="link" href="implementation.html" title="Annex: Implementation">Implementation</a> | |
1329 | section). No compiler has yet been observed to be able to inline function | |
1330 | calls when they use such indirect function pointer calls. Therefore, | |
1331 | inline local functions do not use such indirect function pointer call | |
1332 | (so they are more likely to be optimized) but because of that they | |
1333 | cannot be passed as template parameters. The indirect function pointer | |
1334 | call is needed on <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> | |
1335 | but it is not needed on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> | |
1336 | (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm" target="_top">[N2657]</a> | |
1337 | and <a href="http://www.boost.org/libs/chrono" target="_top">Boost.Config</a>'s | |
1338 | <code class="computeroutput"><span class="identifier">BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS</span></code>) | |
1339 | thus this library automatically generates local function calls that | |
1340 | can be inline on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a> | |
1341 | compilers (even when the local function is not declared inline). | |
1342 | </p></div> | |
1343 | <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> | |
1344 | <span class="bold"><strong>Rationale.</strong></span> This limitation comes from | |
1345 | the fact that the global functor used to pass the local function as a template | |
1346 | parameter (and eventually returned outside the declarations scope) does | |
1347 | not know the local function name so the local function name used for recursive | |
1348 | call cannot be set in the global functor. This limitation together with | |
1349 | preventing the possibility for inlining are the reasons why local functions | |
1350 | are not recursive unless programmers explicitly declare them <code class="computeroutput"><span class="identifier">recursive</span></code>. | |
1351 | </p></div> | |
1352 | <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> | |
1353 | The <code class="computeroutput"><span class="keyword">auto</span></code> storage classifier | |
1354 | is part of the <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/standards" target="_top">C++03</a> | |
1355 | standard and therefore supported by this library. However, the meaning | |
1356 | and usage of the <code class="computeroutput"><span class="keyword">auto</span></code> keyword | |
1357 | changed in <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>. | |
1358 | Therefore, use the <code class="computeroutput"><span class="keyword">auto</span></code> storage | |
1359 | 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> | |
1360 | code that might not work on <a href="http://www.open-std.org/JTC1/SC22/WG21/" target="_top">C++11</a>. | |
1361 | </p></div> | |
1362 | <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> | |
1363 | <span class="bold"><strong>Rationale.</strong></span> The <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION.html" title="Macro BOOST_LOCAL_FUNCTION">BOOST_LOCAL_FUNCTION</a></code> | |
1364 | and <code class="computeroutput"><a class="link" href="../BOOST_LOCAL_FUNCTION_TPL.html" title="Macro BOOST_LOCAL_FUNCTION_TPL">BOOST_LOCAL_FUNCTION_TPL</a></code> | |
1365 | macros internally use <code class="computeroutput"><span class="identifier">__LINE__</span></code> | |
1366 | to generate unique identifiers. Therefore, if these macros are expanded | |
1367 | more than on time on the same line, the generated identifiers will no longer | |
1368 | be unique and the code will not compile. (This restriction does not apply | |
1369 | 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"><a class="link" href="../BOOST_LOCAL_FUNCTION_NAME.html" title="Macro BOOST_LOCAL_FUNCTION_NAME">BOOST_LOCAL_FUNCTION_NAME</a></code> macro | |
1370 | can always be expanded multiple times on the same line because the unique | |
1371 | local function name (and not <code class="computeroutput"><span class="identifier">__LINE__</span></code>) | |
1372 | is used by this macro to generate unique identifiers (so there is no need | |
1373 | for a <code class="computeroutput"><span class="identifier">BOOST_LOCAL_FUNCTION_NAME_ID</span></code> | |
1374 | macro). | |
1375 | </p></div> | |
1376 | <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> | |
1377 | Because there are restrictions on the set of tokens that the preprocessor | |
1378 | can concatenate and because not all compilers correctly implement these | |
1379 | restrictions, it is in general recommended to specify unique identifiers | |
1380 | as a combination of alphanumeric tokens. | |
1381 | </p></div> | |
1382 | <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> | |
1383 | <span class="bold"><strong>Rationale.</strong></span> This is the because a local | |
1384 | function name must be a valid local variable name (the local variable used | |
1385 | to hold the local functor) and operators cannot be used as local variable | |
1386 | names. | |
1387 | </p></div> | |
1388 | </div> | |
1389 | </div> | |
1390 | <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> | |
1391 | <td align="left"></td> | |
1392 | <td align="right"><div class="copyright-footer">Copyright © 2009-2012 Lorenzo | |
1393 | Caminiti<p> | |
1394 | Distributed under the Boost Software License, Version 1.0 (see accompanying | |
1395 | 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>) | |
1396 | </p> | |
1397 | </div></td> | |
1398 | </tr></table> | |
1399 | <hr> | |
1400 | <div class="spirit-nav"> | |
1401 | <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> | |
1402 | </div> | |
1403 | </body> | |
1404 | </html> |