|  | Home | Libraries | People | FAQ | More | 
This section illustrates basic usage of this library.
        Local functions are defined using macros from the header file boost/local_function.hpp. The
        macros must be used from within a declarative context (this is a limitation
        with respect to C++11
        lambda functions which can instead be declared also within expressions):
      
#include <boost/local_function.hpp> // This library header. ... { // Some declarative context. ... result-type BOOST_LOCAL_FUNCTION(parameters) { body-code } BOOST_LOCAL_FUNCTION_NAME(name) ... }
        The code expanded by the macros declares a function object (or functor)
        with the local function name specified by BOOST_LOCAL_FUNCTION_NAME.
        [5] The usual C++ scope visibility rules apply to local functions
        for which a local function is visible only within the enclosing scope in
        which it is declared.
      
        The local function result type is specified just before the BOOST_LOCAL_FUNCTION
        macro.
      
        The local function body is specified using the usual C++ statement syntax
        in a code block { ...
        } between the BOOST_LOCAL_FUNCTION
        and BOOST_LOCAL_FUNCTION_NAME
        macros. The body is specified outside any of the macros so eventual compiler
        error messages and related line numbers retain their usual meaning and format.
        [6]
      
        The local function parameters are passed to the BOOST_LOCAL_FUNCTION
        macro as a comma-separated list of tokens (see the No
        Variadic Macros section for compilers that do not support variadic
        macros):
      
BOOST_LOCAL_FUNCTION(parameter-type1 parameter-name1,parameter-type2 parameter-name2, ...)
        The maximum number of parameters that can be passed to a local function is
        controlled at compile-time by the configuration macro BOOST_LOCAL_FUNCTION_CONFIG_ARITY_MAX.
        For example, let's program a local function named add
        that adds together two integers x
        and y (see also add_params_only.cpp):
      
int BOOST_LOCAL_FUNCTION(int x, int y) { // Local function. return x + y; } BOOST_LOCAL_FUNCTION_NAME(add) BOOST_TEST(add(1, 2) == 3); // Local function call.
        If the local function has no parameter, it is possible to pass void to the BOOST_LOCAL_FUNCTION
        macro (similarly to the C++ syntax that allows to use result-type
        function-name(void) to declare
        a function with no parameter): [7]
      
BOOST_LOCAL_FUNCTION(void) // No parameter.
        For example, let's program a local function that always returns 10 (see also ten_void.cpp):
      
int BOOST_LOCAL_FUNCTION(void) { // No parameter. return 10; } BOOST_LOCAL_FUNCTION_NAME(ten) BOOST_TEST(ten() == 10);
Variables in scope (local variables, enclosing function parameters, data members, etc) can be bound to a local function declaration. Only bound variables, static variables, global variables, functions, and enumerations from the enclosing scope are accessible from within the local function body. The types of bound variables are deduced automatically by this library using Boost.Typeof. [8]
        This library introduces the new "keyword" bind
        [9] which is used in place of the parameter type to specify the name
        of a variable in scope to bind (therefore, bind
        cannot be used as a local function parameter type). A variable can be bound
        by value:
      
bind variable-name // Bind by value.
        Or by reference prefixing the variable name with &:
      
bind& variable-name // Bind by reference.
        Furthermore, the "keyword" bind
        can be prefixed by const to
        bind the variable by constant value:
      
const bind variable-name // Bind by constant value.
Or by constant reference:
const bind& variable-name // Bind by constant value.
        Note that when const is used,
        it must always precede bind.
        [10]
      
If a variable is bound by value, then a copy of the variable value is taken at the point of the local function declaration. If a variable is bound by reference instead, the variable will refer to the value it has at the point of the local function call. Furthermore, it is the programmers' responsibility to ensure that variables bound by reference survive the existence scope of the local function otherwise the bound references will be invalid when the local function is called resulting in undefined behaviour (in other words, the usual care in using C++ references must be taken for variables bound by reference).
The type of a bound variable is automatically deduced using Boost.Typeof and it is the exact same type used to declare such a variable in the enclosing scope with the following notes:
bind...
            is used instead of const bind...
            . However, if a bound variable was not declared constant in the enclosing
            scope then it will not be bound as constant unless constant binding is
            forced using const bind.... (Note that binding by constant reference
            is not supported by C++11
            lambda functions but it is supported by this library.) [11]
          bind&
            or const bind&. [12]
          
        When a variable is bound by value (constant or not), its type must be CopyConstructible (i.e., its must
        provide a copy constructor). As with passing parameters to usual C++ functions,
        programmers might want to bind variables of complex types by (possibly constant)
        reference instead of by value to avoid expensive copy operations when these
        variables are bound to a local function.
      
        For example, let's program the local function add
        from the example in the Introduction
        section. We bind the local variable factor
        by constant value (because its value should not be modified by the local
        function), the local variable sum
        by non-constant reference (because its value needs to be updated with the
        summation result), and program the body to perform the summation (see also
        add.cpp):
      
int main(void) { // Some local scope. int sum = 0, factor = 10; // Variables in scope to bind. void BOOST_LOCAL_FUNCTION(const bind factor, bind& sum, int num) { sum += factor * num; } BOOST_LOCAL_FUNCTION_NAME(add) add(1); // Call the local function. int nums[] = {2, 3}; std::for_each(nums, nums + 2, add); // Pass it to an algorithm. BOOST_TEST(sum == 60); // Assert final summation value. return boost::report_errors(); }
        It is also possible to bind the object this
        when it is in scope (e.g., from an enclosing non-static member function).
        This is done by using the special symbol this_
        (instead of this) as the name
        of the variable to bind in the local function declaration and also to access
        the object within the local function body. [13]
      
| ![[Warning]](../../../../../doc/src/images/warning.png) | Warning | 
|---|---|
| 
          The library will generate a compile-time error if  | 
        The object this can be bound
        by value:
      
bind this_ // Bind the object `this` by value.
        In this case the local function will be able to modify the object when the
        enclosing scope is not a constant member and it will not be able to modify
        the object when the enclosing scope is a constant member. Otherwise, the
        object this can be bound by
        constant value:
      
const bind this_ // Bind the object `this` by constant value.
In this case the local function will never be able to modify the object (regardless of whether the enclosing scope is a constant member or not).
        Note that the object this can
        never be bound by reference because C++ does not allow to obtain a reference
        to this (the library will generate
        a compile-time error if programmers try to use bind& this_
        or const bind& this_).
        Note that this is a pointer
        so the pointed object is never copied even if this
        is bound by value (also it is not possible to directly bind *this because
        *this
        is an expression and not a variable name).
      
        For example, let's program a local function add
        similar to the one in the example from the Introduction
        section but using a member function to illustrate how to bind the object
        this (see also add_this.cpp):
      
struct adder { adder() : sum_(0) {} int sum(const std::vector<int>& nums, const int factor = 10) { void BOOST_LOCAL_FUNCTION(const bind factor, bind this_, int num) { this_->sum_ += factor * num; // Use `this_` instead of `this`. } BOOST_LOCAL_FUNCTION_NAME(add) std::for_each(nums.begin(), nums.end(), add); return sum_; } private: int sum_; };
        Note that the local function has access to all class members via the bound
        object this_ regardless of
        their access level (public,
        protected, or private). [15] Specifically, in the example above the local function updates
        the private data member sum_.
      
        When local functions are programmed within templates, they need to be declared
        using the special macros BOOST_LOCAL_FUNCTION_TPL
        and BOOST_LOCAL_FUNCTION_NAME_TPL:
        [16]
      
#include <boost/local_function.hpp> // This library header. ... { // Some declarative context within a template. ... result-type BOOST_LOCAL_FUNCTION_TPL(parameters) { body-code } BOOST_LOCAL_FUNCTION_NAME_TPL(name) ... }
        The BOOST_LOCAL_FUNCTION_TPL
        and BOOST_LOCAL_FUNCTION_NAME_TPL
        macros have the exact same syntax of the BOOST_LOCAL_FUNCTION
        and BOOST_LOCAL_FUNCTION_NAME
        macros that we have seen so far.
      
        For example, let's program a local function similar to the one from the
        Introduction section
        but within a template (see also add_template.cpp):
      
template<typename T> T total(const T& x, const T& y, const T& z) { T sum = T(), factor = 10; // Must use the `..._TPL` macros within templates. T BOOST_LOCAL_FUNCTION_TPL(const bind factor, bind& sum, T num) { return sum += factor * num; } BOOST_LOCAL_FUNCTION_NAME_TPL(add) add(x); T nums[2]; nums[0] = y; nums[1] = z; std::for_each(nums, nums + 2, add); return sum; }
[5] 
          Rationale. The local function name must
          be passed to the macro BOOST_LOCAL_FUNCTION_NAME
          ending the function definition so this macro can declare a local variable
          with the local function name to hold the local function object. Therefore
          the local function name cannot be specified within the BOOST_LOCAL_FUNCTION
          and it must appear instead after the local function body (even if that
          differs from the usual C++ function declaration syntax).
        
[6] Rationale. If the local function body were instead passed as a macro parameter, it would be expanded on a single line of code (because macros always expand as a single line of code). Therefore, eventual compiler error line numbers would all report the same value and would no longer be useful to pinpoint errors.
[7] 
          Rationale. The C++03
          standard does not allow to pass empty parameters to a macro so the macro
          cannot be invoked as BOOST_LOCAL_FUNCTION(). On C99
          compilers with properly implemented empty macro parameter support, it would
          be possible to allow BOOST_LOCAL_FUNCTION() but this is already not the case for
          MSVC so this syntax is never allowed to ensure better portability.
        
[8] Rationale. By binding a variable in scope, the local function declaration is specifying that such a variable should be accessible within the local function body regardless of its type. Semantically, this binding should be seen as an "extension" of the scope of the bound variable from the enclosing scope to the scope of the local function body. Therefore, contrary to the semantic of passing a function parameter, the semantic of binding a variable does not depend on the variable type but just on the variable name: "The variable in scope named x should be accessible within the local function named f". For example, this reduces maintenance because if a bound variable type is changed, the local function declaration does not have to change.
[9] 
          Obviously, the token bind
          is not a keyword of the C++ language. This library parses the token bind during macro expansion using preprocessor
          meta-programming (see the Implementation
          section). Therefore, bind
          can be considered a new "keyword" only at the preprocessor meta-programming
          level within the syntax defined by the macros of this library (thus it
          is referred to as a "keyword" only within quotes).
        
[10] 
          Rationale. The library macros could have
          been implemented to accept both syntaxes const
          bind ...
          and bind const
          ... equivalently. However, handling
          both syntaxes would have complicated the macro implementation without adding
          any feature so only one syntax const
          bind ...
          is supported.
        
[11] 
              An historical note: Constant binding of variables in scope was the
              main use case that originally motivated the authors in developing this
              library. The authors needed to locally create a chuck of code to assert
              some correctness conditions while these assertions were not supposed
              to modify any of the variables they were using (see the Contract++
              library). This was achieved by binding by constant reference const bind& the variables needed by the assertions
              and then by programming the local function body to check the assertions.
              This way if any of the assertions mistakenly changes a bound variable
              (for example confusing the operator ==
              with =), the compiler
              correctly generates an error because the bound variable is of const type within the local function
              body (see also constant blocks in the Examples
              section).
            
[12] 
              Rationale. Variables originally declared
              as references are bound by value unless [const] bind&
              is used so that references can be bound by both value [const] bind
              and reference [const] bind& (this is the same binding semantic
              adopted by Boost.ScopeExit).
              However, variables originally declared as constants should never loose
              their const qualifier
              (to prevent their modification not just in the enclosing scope but
              also in the local scope) thus they are always bound by constant even
              if bind[&]
              is used instead of const bind[&].
            
[13] 
          Rationale. The special name this_ was chosen following Boost
          practise to postfix with an underscore identifiers that are named
          after keywords (the C++ keyword this
          in this case). The special symbol this_
          is needed because this is
          a reserved C++ keyword so it cannot be used as the name of the internal
          parameter that passes the bound object to the local function body. It would
          have been possible to use this
          (instead of this_) within
          the local function body either at the expenses of copying the bound object
          (which would introduce run-time overhead and also the stringent requirement
          that the bound object must have a deep copy constructor) or by relying
          on an undefined
          behaviour of static_cast
          (which might not work on all platforms at the cost of portability).
        
[14] 
            Rationale. The local function body cannot
            be a static member function of the local functor object in order to support
            recursion (because the local function name is specified by the BOOST_LOCAL_FUNCTION_NAME
            macro only after the body so it must be made available via a functor
            data member named after the local function and local classes cannot have
            static data members in C++) and nesting (because the argument binding
            variable must be declared as a data member so it is visible in a local
            function nested within the body member function) -- see the Implementation
            section. Therefore, from within the local function body the variable
            this is visible but it refers
            to the local functor and not to the bound object.
          
[15] Rationale. This is possible because of the fix to C++ defect 45 that made inner and local types able to access all outer class members regardless of their access level.
[16] 
          Rationale. Within templates, this library
          needs to use typename to explicitly
          indicate that some expressions evaluate to a type. Because C++03
          does not allow to use typename
          outside templates, the special ..._TPL macros are used to indicate that
          the enclosing scope is a template so this library can safely use typename to resolve expression type ambiguities.
          C++11 and
          other compilers might compile local functions within templates even when
          the ..._TPL
          macros are not used. However, it is recommended to always use the ..._TPL
          macros within templates to maximize portability.