]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/local_function/doc/advanced_topics.qbk
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / local_function / doc / advanced_topics.qbk
1
2 [/ Copyright (C) 2009-2012 Lorenzo Caminiti ]
3 [/ Distributed under the Boost Software License, Version 1.0 ]
4 [/ (see accompanying file LICENSE_1_0.txt or a copy at ]
5 [/ http://www.boost.org/LICENSE_1_0.txt) ]
6 [/ Home at http://www.boost.org/libs/local_function ]
7
8 [section Advanced Topics]
9
10 This section illustrates advanced usage of this library.
11 At the bottom there is also a list of known limitations of this library.
12
13 [section Default Parameters]
14
15 This library allows to specify default values for the local function parameters.
16 However, the usual C++ syntax for default parameters that uses the assignment symbol `=` cannot be used.
17 [footnote
18 *Rationale.*
19 The assignment symbol `=` cannot be used to specify default parameter values because default values are not part of the parameter type so they cannot be handled using template meta-programming.
20 Default parameter values need to be separated from the rest of the parameter declaration using the preprocessor.
21 Specifically, this library needs to use preprocessor meta-programming to remove default values when constructing the local function type and also to count the number of default values to provide the correct set of call operators for the local functor.
22 Therefore, the symbol `=` cannot be used because it cannot be handled by preprocessor meta-programming (non-alphanumeric symbols cannot be detected by preprocessor meta-programming because they cannot be concatenated by the preprocessor).
23 ]
24 The keyword `default` is used instead:
25
26 ``[^/parameter-type parameter-name/]``, default`` [^/parameter-default-value/]``, ...
27
28 For example, let's program a local function `add(x, y)` where the second parameter `y` is optional and has a default value of `2` (see also [@../../test/add_default.cpp =add_default.cpp=]):
29
30 [add_default]
31
32 Programmers can define a `WITH_DEFAULT` macro similar to the following if they think it improves readability over the above syntax (see also [@../../test/add_with_default.cpp =add_with_default.cpp=]):
33 [footnote
34 The authors do not personally find the use of the `WITH_DEFAULT` macro more readable and they prefer to use the `default` keyword directly.
35 Furthermore, `WITH_DEFAULT` needs to be defined differently for compilers without variadic macros `#define WITH_DEFAULT (default)` so it can only be defined by programmers based on the syntax they decide to use (see the __No_Variadic_Macros__ section).
36 ]
37
38 [add_with_default_macro]
39 [add_with_default]
40
41 [endsect]
42
43 [section Commas and Symbols in Macros]
44
45 The C++ preprocessor does not allow commas `,` within macro parameters unless they are wrapped by round parenthesis `()` (see the __Boost_Utility_IdentityType__ documentation for details).
46 Therefore, using commas within local function parameters and bindings will generate (cryptic) preprocessor errors unless they are wrapped with an extra set of round parenthesis `()` as explained here.
47
48 [note
49 Also macro parameters with commas wrapped by angular parenthesis `<>` (templates, etc) or square parenthesis `[]` (multidimensional array access, etc) need to be wrapped by the extra round parenthesis `()` as explained here (this is because the preprocessor only recognizes the round parenthesis and it does not recognize angular, square, or any other type of parenthesis).
50 However, macro parameters with commas which are already wrapped by round parenthesis `()` are fine (function calls, some value expressions, etc).
51 ]
52
53 In addition, local function parameter types cannot start with non-alphanumeric symbols (alphanumeric symbols are `A-Z`, `a-z`, and `0-9`).
54 [footnote
55 *Rationale.*
56 This limitation is because this library uses preprocessor token concatenation [^##] to inspect the macro parameters (to distinguish between function parameters, bound variables, etc) and the C++ preprocessor does not allow to concatenate non-alphanumeric tokens.
57 ]
58 The library will generate (cryptic) preprocessor errors if a parameter type starts with a non-alphanumeric symbol.
59
60 Let's consider the following example:
61
62 void BOOST_LOCAL_FUNCTION(
63 const std::map<std::string, size_t>& m, // (1) Error.
64 ::sign_t sign, // (2) Error.
65 const size_t& factor,
66 default key_sizeof<std::string, size_t>::value, // (3) Error.
67 const std::string& separator, default cat(":", " ") // (4) OK.
68 ) {
69 ...
70 } BOOST_LOCAL_FUNCTION_NAME(f)
71
72 [*(1)] The parameter type `const std::map<std::string, size_t>&` contains a comma `,` after the first template parameter `std::string`.
73 This comma is not wrapped by any round parenthesis `()` thus it will cause a preprocessor error.
74 [footnote
75 The preprocessor always interprets unwrapped commas as separating macro parameters.
76 Thus in this case the comma will indicate to the preprocessor that the first macro parameter is `const std::map<std::tring`, the second macro parameter is `size_t>& m`, etc instead of passing `const std::map<std::string, size_t>& m` as a single macro parameter.
77 ]
78 The __Boost_Utility_IdentityType__ macro `BOOST_IDENTITY_TYPE((`[^['type-with-commas]]`))` defined in the =boost/utility/identity_type.hpp= header can be used to wrap a type within extra parenthesis `()` so to overcome this problem:
79
80 #include <boost/utility/identity_type.hpp>
81
82 void BOOST_LOCAL_FUNCTION(
83 BOOST_IDENTITY_TYPE((const std::map<std::string, size_t>&)) m, // OK.
84 ...
85 ) {
86 ...
87 } BOOST_LOCAL_FUNCTION_NAME(f)
88
89 This macro expands to an expression that evaluates (at compile-time) exactly to the specified type (furthermore, this macro does not use variadic macros so it works on any __CXX03__ compiler).
90 Note that a total of two set of parenthesis `()` are needed: The parenthesis to invoke the `BOOST_IDENTITY_TYPE(...)` macro plus the parenthesis to wrap the type expression (and therefore any comma `,` that it contains) passed as parameter to the `BOOST_IDENTITY_TYPE((...))` macro.
91 Finally, the `BOOST_IDENTITY_TYPE` macro must be prefixed by the `typename` keyword `typename BOOST_IDENTITY_TYPE(`[^['parenthesized-type]]`)` when used together with the [macroref BOOST_LOCAL_FUNCTION_TPL] macro within templates.
92
93 [note
94 Often, there might be better ways to overcome this limitation that lead to code which is more readable than the one using the `BOOST_IDENTITY_TYPE` macro.
95 ]
96
97 For example, in this case a `typedef` from the enclosing scope could have been used to obtain the following valid and perhaps more readable code:
98
99 typedef std::map<std::string, size_t> map_type;
100 void BOOST_LOCAL_FUNCTION(
101 const map_type& m, // OK (and more readable).
102 ...
103 ) BOOST_LOCAL_FUNCTION_NAME(f)
104
105 [*(2)] The parameter type `::sign_t` starts with the non-alphanumeric symbols `::` thus it will generate preprocessor errors if used as a local function parameter type.
106 The `BOOST_IDENTITY_TYPE` macro can also be used to overcome this issue:
107
108 void BOOST_LOCAL_FUNCTION(
109 ...
110 BOOST_IDENTITY_TYPE((::sign_t)) sign, // OK.
111 ...
112 ) {
113 ...
114 } BOOST_LOCAL_FUNCTION_NAME(f)
115
116 [note
117 Often, there might be better ways to overcome this limitation that lead to code which is more readable than the one using the `BOOST_IDENTITY_TYPE` macro.
118 ]
119
120 For example, in this case the symbols `::` could have been simply dropped to obtain the following valid and perhaps more readable code:
121
122 void BOOST_LOCAL_FUNCTION(
123 ...
124 sign_t sign, // OK (and more readable).
125 ...
126 ) {
127 ...
128 } BOOST_LOCAL_FUNCTION_NAME(f)
129
130 [*(3)] The default parameter value `key_sizeof<std::string, size_t>::value` contains a comma `,` after the first template parameter `std::string`.
131 Again, this comma is not wrapped by any parenthesis `()` so it will cause a preprocessor error.
132 Because this is a value expression (and not a type expression), it can simply be wrapped within an extra set of round parenthesis `()`:
133
134 void BOOST_LOCAL_FUNCTION(
135 ...
136 const size_t& factor,
137 default (key_sizeof<std::string, size_t>::value), // OK.
138 ...
139 ) {
140 ...
141 } BOOST_LOCAL_FUNCTION_NAME(f)
142
143 [*(4)] The default parameter value `cat(":", " ")` is instead fine because it contains a comma `,` which is already wrapped by the parenthesis `()` of the function call `cat(...)`.
144
145 Consider the following complete example (see also [@../../test/macro_commas.cpp =macro_commas.cpp=]):
146
147 [macro_commas]
148
149 [endsect]
150
151 [section Assignments and Returns]
152
153 Local functions are function objects so it is possible to assign them to other functors like __Boost_Function__'s `boost::function` in order to store the local function into a variable, pass it as a parameter to another function, or return it from the enclosing function.
154
155 For example (see also [@../../test/return_assign.cpp =return_assign.cpp=]):
156
157 [return_assign]
158
159 [warning
160 As with __CXX11_lambda_functions__, programmers are responsible to ensure that bound variables are valid in any scope where the local function object is called.
161 Returning and calling a local function outside its declaration scope will lead to undefined behaviour if any of the bound variable is no longer valid in the scope where the local function is called (see the __Examples__ section for more examples on the extra care needed when returning a local function as a closure).
162 It is always safe instead to call a local function within its enclosing scope.
163 ]
164
165 In addition, a local function can bind and call other local functions.
166 Local functions should always be bound by constant reference `const bind&` to avoid unnecessary copies.
167 For example, the following local function `inc_sum` binds the local function `inc` so `inc_sum` can call `inc` (see aslo [@../../test/transform.cpp =transform.cpp=]):
168
169 [transform]
170
171 [endsect]
172
173 [section Nesting]
174
175 It is possible to nest local functions into one another.
176 For example (see also [@../../test/nesting.cpp =nesting.cpp=]):
177
178 [nesting]
179
180 [endsect]
181
182 [section Accessing Types (concepts, etc)]
183
184 This library never requires to explicitly specify the type of bound variables (e.g., this reduces maintenance because the local function declaration and definition do not have to change even if the bound variable types change as long as the semantics of the local function remain valid).
185 From within local functions, programmers can access the type of a bound variable using the following macro:
186
187 BOOST_LOCAL_FUNCTION_TYPEOF(``/bound-variable-name/``)
188
189 The [macroref BOOST_LOCAL_FUNCTION_TYPEOF] macro expands to a type expression that evaluates (at compile-time) to the fully qualified type of the bound variable with the specified name.
190 This type expression is fully qualified in the sense that it will be constant if the variable is bound by constant `const bind[&]` and it will also be a reference if the variable is bound by reference `[const] bind&` (if needed, programmers can remove the `const` and `&` qualifiers using `boost::remove_const` and `boost::remove_reference`, see __Boost_TypeTraits__).
191
192 The deduced bound type can be used within the body to check concepts, declare local variables, etc.
193 For example (see also [@../../test/typeof.cpp =typeof.cpp=] and [@../../test/addable.hpp =addable.hpp=]):
194
195 [typeof]
196
197 Within templates, [macroref BOOST_LOCAL_FUNCTION_TYPEOF] should not be prefixed by the `typename` keyword but eventual type manipulations need the `typename` prefix as usual (see also [@../../test/typeof_template.cpp =typeof_template.cpp=] and [@../../test/addable.hpp =addable.hpp=]):
198
199 [typeof_template]
200
201 In this context, it is best to use the [macroref BOOST_LOCAL_FUNCTION_TYPEOF] macro instead of using __Boost_Typeof__ to reduce the number of times that __Boost_Typeof__ is invoked (either the library already internally used __Boost_Typeof__ once, in which case using this macro will not use __Boost_Typeof__ again, or the bound variable type is explicitly specified by programmers as shown be below, in which case using this macro will not use __Boost_Typeof__ at all).
202
203 Furthermore, within the local function body it possible to access the result type using `result_type`, the type of the first parameter using `arg1_type`, the type of the second parameter using `arg2_type`, etc.
204 [footnote
205 *Rationale.*
206 The type names `result_type` and `arg`[^['N]]`_type` follow the __Boost_TypeTraits__ naming conventions for function traits.
207 ]
208
209 [endsect]
210
211 [section Specifying Types (no Boost.Typeof)]
212
213 While not required, it is possible to explicitly specify the type of bound variables so the library will not internally use __Boost_Typeof__ to automatically deduce the types.
214 When specified, the bound variable type must follow the `bind` "keyword" and it must be wrapped within round parenthesis `()`:
215
216 bind(``/variable-type/``) ``/variable-name/`` // Bind by value with explicit type.
217 bind(``/variable-type/``)& ``/variable-name/`` // Bind by reference with explicit type.
218 const bind(``/variable-type/``) ``/variable-name/`` // Bind by constant value with explicit type.
219 const bind(``/variable-type/``)& ``/variable-name/`` // Bind by constant reference with explicit type.
220 bind(``/class-type/``*) this_ // Bind object `this` with explicit type.
221 const bind(``/class-type/``*) this_ // Bind object `this` by constant with explicit type.
222
223 Note that within the local function body it is always possible to abstract the access to the type of a bound variable using [macroref BOOST_LOCAL_FUNCTION_TYPEOF] (even when the bound variable type is explicitly specified in the local function declaration).
224
225 The library also uses __Boost_Typeof__ to determine the local function result type (because this type is specified outside the [macroref BOOST_LOCAL_FUNCTION] macro).
226 Thus it is also possible to specify the local function result type as one of the [macroref BOOST_LOCAL_FUNCTION] macro parameters prefixing it by `return` so the library will not use __Boost_Typeof__ to deduce the result type:
227
228 BOOST_LOCAL_FUNCTION_TYPE(return ``[^/result-type/]``, ...)
229
230 Note that the result type must be specified only once either before the macro (without the `return` prefix) or as one of the macro parameters (with the `return` prefix).
231 As always, the result type can be `void` to declare a function that returns nothing (so `return void` is allowed when the result type is specified as one of the macro parameters).
232
233 The following example specifies all bound variables and result types (see also [@../../test/add_typed.cpp =add_typed.cpp=]):
234 [footnote
235 In the examples of this documentation, bound variables, function parameters, and the result type are specified in this order because this is the order used by __CXX11_lambda_functions__.
236 However, the library accepts bound variables, function parameters, and the result type in any order.
237 ]
238
239 [add_typed]
240
241 Unless necessary, it is recommended to not specify the bound variable and result types.
242 Let the library deduce these types so the local function syntax will be more concise and the local function declaration will not have to change if a bound variable type changes (reducing maintenance).
243
244 [note
245 When all bound variable and result types are explicitly specified, the library implementation will not use __Boost_Typeof__.
246 ]
247
248 [endsect]
249
250 [section Inlining]
251
252 Local functions can be declared [@http://en.wikipedia.org/wiki/Inline_function inline] to increase the chances that the compiler will be able to reduce the run-time of the local function call by inlining the generated assembly code.
253 A local function is declared inline by prefixing its name with the keyword `inline`:
254
255 ``/result-type/`` BOOST_LOCAL_FUNCTION(``/parameters/``) {
256 ... // Body.
257 } BOOST_LOCAL_FUNCTION_NAME(inline ``/name/``) // Inlining.
258
259 When inlining a local function, note the following:
260
261 * On __CXX03__ compliant compilers, inline local functions always have a run-time comparable to their equivalent implementation that uses local functors (see the __Alternatives__ section).
262 However, inline local functions have the important limitation that they cannot be assigned to other functors (like `boost::function`) and they cannot be passed as template parameters.
263 * On __CXX11__ compilers, `inline` has no effect because this library will automatically generate code that uses __CXX11__ specific features to inline the local function calls whenever possible even if the local function is not declared inline.
264 Furthermore, non __CXX11__ local functions can always be passes as template parameters even when they are declared inline.
265 [footnote
266 *Rationale.*
267 This library uses an indirect function call via a function pointer in order to pass the local function as a template parameter (see the __Implementation__ section).
268 No compiler has yet been observed to be able to inline function calls when they use such indirect function pointer calls.
269 Therefore, inline local functions do not use such indirect function pointer call (so they are more likely to be optimized) but because of that they cannot be passed as template parameters.
270 The indirect function pointer call is needed on __CXX03__ but it is not needed on __CXX11__ (see __N2657__ and __Boost_Config__'s `BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS`) thus this library automatically generates local function calls that can be inline on __CXX11__ compilers (even when the local function is not declared inline).
271 ]
272
273 [important
274 It is recommended to not declare a local function inline unless it is strictly necessary for optimizing pure __CXX03__ compliant code (because in all other cases this library will automatically take advantage of __CXX11__ features to optimize the local function calls while always allowing to pass the local function as a template parameter).
275 ]
276
277 For example, the following local function is declared inline (thus a for-loop needs to be used for portability instead of passing the local function as a template parameter to the `std::for_each` algorithm, see also [@../../test/add_inline.cpp =add_inline.cpp=]):
278
279 [add_inline]
280
281 [endsect]
282
283 [section Recursion]
284
285 Local functions can be declared [@http://en.wikipedia.org/wiki/Recursion_(computer_science)#Recursive_procedures recursive] so a local function can recursively call itself from its body (as usual with C++ functions).
286 A local function is declared recursive by prefixing its name with the `recursive` "keyword" (thus `recursive` cannot be used as a local function name):
287
288 ``/result-type/`` BOOST_LOCAL_FUNCTION(``/parameters/``) {
289 ... // Body.
290 } BOOST_LOCAL_FUNCTION_NAME(recursive ``/name/``) // Recursive.
291
292 For example, the following local function is used to recursively calculate the factorials of all the numbers in the specified vector (see also [@../../test/factorial.cpp =factorial.cpp=]):
293
294 [factorial]
295
296 Compilers have not been observed to be able to inline recursive local function calls not even when the recursive local function is also declared inline:
297
298 ... BOOST_LOCAL_FUNCTION_NAME(inline recursive factorial)
299
300 Recursive local functions should never be called outside their declaration scope.
301 [footnote
302 *Rationale.*
303 This limitation comes from the fact that the global functor used to pass the local function as a template parameter (and eventually returned outside the declarations scope) does not know the local function name so the local function name used for recursive call cannot be set in the global functor.
304 This limitation together with preventing the possibility for inlining are the reasons why local functions are not recursive unless programmers explicitly declare them `recursive`.
305 ]
306
307 [warning
308 If a local function is returned from the enclosing function and called in a different scope, the behaviour is undefined (and it will likely result in a run-time error).
309 ]
310
311 This is not a limitation with respect to __CXX11_lambda_functions__ because lambdas can never call themselves recursively (in other words, there is no recursive lambda function that can successfully be called outside its declaration scope because there is no recursive lambda function at all).
312
313 [endsect]
314
315 [section Overloading]
316
317 Because local functions are functors, it is possible to overload them using the `boost::overloaded_function` functor of __Boost_Functional_OverloadedFunction__ from the =boost/functional/overloaded_function.hpp= header (see the __Boost_Functional_OverloadedFunction__ documentation for details).
318
319 In the following example, the overloaded function object `add` can be called with signatures from either the local function `add_s`, or the local function `add_d`, or the local function `add_d` with its extra default parameter, or the function pointer `add_i` (see also [@../../test/overload.cpp =overload.cpp=]):
320
321 [overload_decl]
322 [overload]
323
324 [endsect]
325
326 [section Exception Specifications]
327
328 It is possible to program exception specifications for local functions by specifying them after the [macroref BOOST_LOCAL_FUNCTION] macro and before the body code block `{ ... }`.
329
330 [important
331 Note that the exception specifications only apply to the body code specified by programmers and they do not apply to the rest of the code automatically generated by the macro expansions to implement local functions.
332 For example, even if the body code is specified to throw no exception using `throw () { ... }`, the execution of the library code automatically generated by the macros could still throw (if there is no memory, etc).
333 ]
334
335 For example (see also [@../../test/add_except.cpp =add_except.cpp=]):
336
337 [add_except]
338
339 [endsect]
340
341 [section Storage Classifiers]
342
343 Local function parameters support the storage classifiers as usual in __CXX03__.
344 The `auto` storage classifier is specified as:
345 [footnote
346 The `auto` storage classifier is part of the __CXX03__ standard and therefore supported by this library.
347 However, the meaning and usage of the `auto` keyword changed in __CXX11__.
348 Therefore, use the `auto` storage classifier with the usual care in order to avoid writing __CXX03__ code that might not work on __CXX11__.
349 ]
350
351 auto ``/parameter-type parameter-name/``
352
353 The `register` storage classifier is specified as:
354
355 register ``/parameter-type parameter-name/``
356
357 For example (see also [@../../test/add_classifiers.cpp =add_classifiers.cpp=]):
358
359 [add_classifiers]
360
361 [endsect]
362
363 [section Same Line Expansions]
364
365 In general, it is not possible to expand the [macroref BOOST_LOCAL_FUNCTION], [macroref BOOST_LOCAL_FUNCTION_TPL] macros multiple times on the same line.
366 [footnote
367 *Rationale.*
368 The [macroref BOOST_LOCAL_FUNCTION] and [macroref BOOST_LOCAL_FUNCTION_TPL] macros internally use `__LINE__` to generate unique identifiers.
369 Therefore, if these macros are expanded more than on time on the same line, the generated identifiers will no longer be unique and the code will not compile.
370 (This restriction does not apply to MSVC and other compilers that provide the non-standard `__COUNTER__` macro.)
371 Note that the [macroref BOOST_LOCAL_FUNCTION_NAME] macro can always be expanded multiple times on the same line because the unique local function name (and not `__LINE__`) is used by this macro to generate unique identifiers (so there is no need for a `BOOST_LOCAL_FUNCTION_NAME_ID` macro).
372 ]
373
374 Therefore, this library provides additional macros [macroref BOOST_LOCAL_FUNCTION_ID] and [macroref BOOST_LOCAL_FUNCTION_ID_TPL] which can be expanded multiple times on the same line as long as programmers specify unique identifiers as the macros' first parameters.
375 The unique identifier can be any token (not just numeric) that can be successfully concatenated by the preprocessor (e.g., `local_function_number_1_at_line_123`).
376 [footnote
377 Because there are restrictions on the set of tokens that the preprocessor can concatenate and because not all compilers correctly implement these restrictions, it is in general recommended to specify unique identifiers as a combination of alphanumeric tokens.
378 ]
379
380 The [macroref BOOST_LOCAL_FUNCTION_ID] and [macroref BOOST_LOCAL_FUNCTION_ID_TPL] macros accept local function parameter declaration lists using the exact same syntax as [macroref BOOST_LOCAL_FUNCTION].
381 For example (see also [@../../test/same_line.cpp =same_line.cpp=]):
382
383 [same_line]
384
385 As shown by the example above, the [macroref BOOST_LOCAL_FUNCTION_ID] and [macroref BOOST_LOCAL_FUNCTION_ID_TPL] macros are especially useful when it is necessary to invoke them multiple times within a user-defined macro (because the preprocessor expands all nested macros on the same line).
386
387 [endsect]
388
389 [section Limitations (operators, etc)]
390
391 The following table summarizes all C++ function features indicating those features that are not supported by this library for local functions.
392
393 [table
394 [
395 [ C++ Function Feature ]
396 [ Local Function Support ]
397 [ Comment ]
398 ]
399 [
400 [ `export` ]
401 [ No. ]
402 [ This is not supported because local functions cannot be templates (plus most C++ compilers do not implement `export` at all). ]
403 ]
404 [
405 [ `template<`[^['template-parameter-list]]`>` ]
406 [ No. ]
407 [ This is not supported because local functions are implemented using local classes and __CXX03__ local classes cannot be templates. ]
408 ]
409 [
410 [ `explicit` ]
411 [ No. ]
412 [ This is not supported because local functions are not constructors. ]
413 ]
414 [
415 [ `inline` ]
416 [ Yes. ]
417 [ Local functions can be specified `inline` to improve the chances that __CXX03__ compilers can optimize the local function call run-time (but `inline` local functions cannot be passed as template parameters on __CXX03__ compilers, see the __Advanced_Topics__ section). ]
418 ]
419 [
420 [ `extern` ]
421 [ No. ]
422 [ This is not supported because local functions are always defined locally within the enclosing scope and together with their declarations. ]
423 ]
424 [
425 [ `static` ]
426 [ No. ]
427 [ This is not supported because local functions are not member functions. ]
428 ]
429 [
430 [ `virtual` ]
431 [ No. ]
432 [ This is not supported because local functions are not member functions.
433 [footnote
434 *Rationale.*
435 It would be possible to make a local function class inherit from another local function class.
436 However, this "inheritance" feature is not implemented because it seemed of [@http://lists.boost.org/Archives/boost/2010/09/170895.php no use] given that local functions can be bound to one another thus they can simply call each other directly without recurring to dynamic binding or base function calls.
437 ]
438 ]
439 ]
440 [
441 [ [^/result-type/] ]
442 [ Yes. ]
443 [ This is supported (see the __Tutorial__ section). ]
444 ]
445 [
446 [ [^/function-name/] ]
447 [ Yes. ]
448 [ Local functions are named and they can call themselves recursively but they cannot be operators (see the __Tutorial__ and __Advanced_Topics__ sections). ]
449 ]
450 [
451 [ [^/parameter-list/] ]
452 [ Yes. ]
453 [ This is supported and it also supports the `auto` and `register` storage classifiers, default parameters, and binding of variables in scope (see the __Tutorial__ and __Advanced_Topics__ sections). ]
454 ]
455 [
456 [ Trailing `const` qualifier ]
457 [ No. ]
458 [ This is not supported because local functions are not member functions. ]
459 ]
460 [
461 [ Trailing `volatile` qualifier ]
462 [ No. ]
463 [ This is not supported because local functions are not member functions. ]
464 ]
465 ]
466
467 [heading Operators]
468
469 Local functions cannot be operators.
470 Naming a local function `operator...` will generate a compile-time error.
471 [footnote
472 *Rationale.*
473 This is the because a local function name must be a valid local variable name (the local variable used to hold the local functor) and operators cannot be used as local variable names.
474 ]
475
476 For example, the following code does not compile (see also [@../../test/operator_error.cpp =operator_error.cpp=]):
477
478 [operator_error]
479
480 [heading Goto]
481
482 It is possible to jump with a `goto` within the local function body.
483 For example, the following compiles (see also [@../../test/goto.cpp =goto.cpp=]):
484
485 [goto]
486
487 However, it is not possible to jump with a `goto` from within the local function body to to a label defined in the enclosing scope.
488 For example, the following does not compile (see also [@../../test/goto_error.cpp =goto_error.cpp=]):
489
490 [goto_error]
491
492 [endsect]
493
494 [endsect]
495