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 10This section illustrates advanced usage of this library. 11At the bottom there is also a list of known limitations of this library. 12 13[section Default Parameters] 14 15This library allows to specify default values for the local function parameters. 16However, the usual C++ syntax for default parameters that uses the assignment symbol `=` cannot be used. 17[footnote 18*Rationale.* 19The 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. 20Default parameter values need to be separated from the rest of the parameter declaration using the preprocessor. 21Specifically, 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. 22Therefore, 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] 24The keyword `default` is used instead: 25 26 ``[^/parameter-type parameter-name/]``, default`` [^/parameter-default-value/]``, ... 27 28For 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 32Programmers 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 34The authors do not personally find the use of the `WITH_DEFAULT` macro more readable and they prefer to use the `default` keyword directly. 35Furthermore, `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 45The C++ preprocessor does not allow commas `,` within macro parameters unless they are wrapped by round parenthesis `()` (see the __Boost_Utility_IdentityType__ documentation for details). 46Therefore, 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 49Also 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). 50However, macro parameters with commas which are already wrapped by round parenthesis `()` are fine (function calls, some value expressions, etc). 51] 52 53In 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.* 56This 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] 58The library will generate (cryptic) preprocessor errors if a parameter type starts with a non-alphanumeric symbol. 59 60Let'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`. 73This comma is not wrapped by any round parenthesis `()` thus it will cause a preprocessor error. 74[footnote 75The preprocessor always interprets unwrapped commas as separating macro parameters. 76Thus 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] 78The __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 89This 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). 90Note 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. 91Finally, 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 94Often, 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 97For 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. 106The `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 117Often, 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 120For 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`. 131Again, this comma is not wrapped by any parenthesis `()` so it will cause a preprocessor error. 132Because 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 145Consider 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 153Local 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 155For example (see also [@../../test/return_assign.cpp =return_assign.cpp=]): 156 157[return_assign] 158 159[warning 160As with __CXX11_lambda_functions__, programmers are responsible to ensure that bound variables are valid in any scope where the local function object is called. 161Returning 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). 162It is always safe instead to call a local function within its enclosing scope. 163] 164 165In addition, a local function can bind and call other local functions. 166Local functions should always be bound by constant reference `const bind&` to avoid unnecessary copies. 167For 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 175It is possible to nest local functions into one another. 176For example (see also [@../../test/nesting.cpp =nesting.cpp=]): 177 178[nesting] 179 180[endsect] 181 182[section Accessing Types (concepts, etc)] 183 184This 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). 185From 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 189The [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. 190This 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 192The deduced bound type can be used within the body to check concepts, declare local variables, etc. 193For example (see also [@../../test/typeof.cpp =typeof.cpp=] and [@../../test/addable.hpp =addable.hpp=]): 194 195[typeof] 196 197Within 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 201In 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 203Furthermore, 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.* 206The 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 213While 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. 214When 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 223Note 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 225The library also uses __Boost_Typeof__ to determine the local function result type (because this type is specified outside the [macroref BOOST_LOCAL_FUNCTION] macro). 226Thus 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 230Note 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). 231As 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 233The following example specifies all bound variables and result types (see also [@../../test/add_typed.cpp =add_typed.cpp=]): 234[footnote 235In 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__. 236However, the library accepts bound variables, function parameters, and the result type in any order. 237] 238 239[add_typed] 240 241Unless necessary, it is recommended to not specify the bound variable and result types. 242Let 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 245When 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 252Local 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. 253A 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 259When 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). 262However, 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. 264Furthermore, non __CXX11__ local functions can always be passes as template parameters even when they are declared inline. 265[footnote 266*Rationale.* 267This 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). 268No compiler has yet been observed to be able to inline function calls when they use such indirect function pointer calls. 269Therefore, 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. 270The 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 274It 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 277For 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 285Local 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). 286A 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 292For 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 296Compilers 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 300Recursive local functions should never be called outside their declaration scope. 301[footnote 302*Rationale.* 303This 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. 304This 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 308If 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 311This 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 317Because 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 319In 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 328It 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 331Note 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. 332For 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 335For example (see also [@../../test/add_except.cpp =add_except.cpp=]): 336 337[add_except] 338 339[endsect] 340 341[section Storage Classifiers] 342 343Local function parameters support the storage classifiers as usual in __CXX03__. 344The `auto` storage classifier is specified as: 345[footnote 346The `auto` storage classifier is part of the __CXX03__ standard and therefore supported by this library. 347However, the meaning and usage of the `auto` keyword changed in __CXX11__. 348Therefore, 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 353The `register` storage classifier is specified as: 354 355 register ``/parameter-type parameter-name/`` 356 357[endsect] 358 359[section Same Line Expansions] 360 361In general, it is not possible to expand the [macroref BOOST_LOCAL_FUNCTION], [macroref BOOST_LOCAL_FUNCTION_TPL] macros multiple times on the same line. 362[footnote 363*Rationale.* 364The [macroref BOOST_LOCAL_FUNCTION] and [macroref BOOST_LOCAL_FUNCTION_TPL] macros internally use `__LINE__` to generate unique identifiers. 365Therefore, 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. 366(This restriction does not apply to MSVC and other compilers that provide the non-standard `__COUNTER__` macro.) 367Note 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). 368] 369 370Therefore, 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. 371The 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`). 372[footnote 373Because 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. 374] 375 376The [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]. 377For example (see also [@../../test/same_line.cpp =same_line.cpp=]): 378 379[same_line] 380 381As 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). 382 383[endsect] 384 385[section Limitations (operators, etc)] 386 387The following table summarizes all C++ function features indicating those features that are not supported by this library for local functions. 388 389[table 390[ 391 [ C++ Function Feature ] 392 [ Local Function Support ] 393 [ Comment ] 394] 395[ 396 [ `export` ] 397 [ No. ] 398 [ This is not supported because local functions cannot be templates (plus most C++ compilers do not implement `export` at all). ] 399] 400[ 401 [ `template<`[^['template-parameter-list]]`>` ] 402 [ No. ] 403 [ This is not supported because local functions are implemented using local classes and __CXX03__ local classes cannot be templates. ] 404] 405[ 406 [ `explicit` ] 407 [ No. ] 408 [ This is not supported because local functions are not constructors. ] 409] 410[ 411 [ `inline` ] 412 [ Yes. ] 413 [ 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). ] 414] 415[ 416 [ `extern` ] 417 [ No. ] 418 [ This is not supported because local functions are always defined locally within the enclosing scope and together with their declarations. ] 419] 420[ 421 [ `static` ] 422 [ No. ] 423 [ This is not supported because local functions are not member functions. ] 424] 425[ 426 [ `virtual` ] 427 [ No. ] 428 [ This is not supported because local functions are not member functions. 429[footnote 430*Rationale.* 431It would be possible to make a local function class inherit from another local function class. 432However, 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. 433] 434 ] 435] 436[ 437 [ [^/result-type/] ] 438 [ Yes. ] 439 [ This is supported (see the __Tutorial__ section). ] 440] 441[ 442 [ [^/function-name/] ] 443 [ Yes. ] 444 [ Local functions are named and they can call themselves recursively but they cannot be operators (see the __Tutorial__ and __Advanced_Topics__ sections). ] 445] 446[ 447 [ [^/parameter-list/] ] 448 [ Yes. ] 449 [ 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). ] 450] 451[ 452 [ Trailing `const` qualifier ] 453 [ No. ] 454 [ This is not supported because local functions are not member functions. ] 455] 456[ 457 [ Trailing `volatile` qualifier ] 458 [ No. ] 459 [ This is not supported because local functions are not member functions. ] 460] 461] 462 463[heading Operators] 464 465Local functions cannot be operators. 466Naming a local function `operator...` will generate a compile-time error. 467[footnote 468*Rationale.* 469This 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. 470] 471 472For example, the following code does not compile (see also [@../../test/operator_error.cpp =operator_error.cpp=]): 473 474[operator_error] 475 476[heading Goto] 477 478It is possible to jump with a `goto` within the local function body. 479For example, the following compiles (see also [@../../test/goto.cpp =goto.cpp=]): 480 481[goto] 482 483However, it is not possible to jump with a `goto` from within the local function body to to a label defined in the enclosing scope. 484For example, the following does not compile (see also [@../../test/goto_error.cpp =goto_error.cpp=]): 485 486[goto_error] 487 488[endsect] 489 490[endsect] 491 492