mirror of
https://github.com/boostorg/phoenix.git
synced 2026-02-10 11:42:16 +00:00
94 lines
3.5 KiB
Plaintext
94 lines
3.5 KiB
Plaintext
[/==============================================================================
|
|
Copyright (C) 2001-2010 Joel de Guzman
|
|
Copyright (C) 2001-2005 Dan Marsden
|
|
Copyright (C) 2001-2010 Thomas Heller
|
|
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
===============================================================================/]
|
|
|
|
[section Function]
|
|
|
|
#include <boost/phoenix/function.hpp>
|
|
|
|
The `function` class template provides a mechanism for implementing lazily
|
|
evaluated functions. Syntactically, a lazy function looks like an ordinary C/C++ function.
|
|
The function call looks familiar and feels the same as ordinary C++ functions.
|
|
However, unlike ordinary functions, the actual function execution is deferred.
|
|
|
|
Unlike ordinary function pointers or functor objects that need to be explicitly bound through the bind function (see [link phoenix.reference.modules.bind Bind]),
|
|
the argument types of these functions are automatically lazily bound.
|
|
|
|
In order to create a lazy function, we need to implement a model of the
|
|
FunctionEval concept. For a function that takes `N` arguments, a model of FunctionEval must
|
|
provide:
|
|
|
|
* An `operator()` that takes `N` arguments, and implements
|
|
the function logic.
|
|
* A nested metafunction `result<Signature>` or nested typedef `result_type`, following __boost_result_of__
|
|
|
|
[/
|
|
* A nested metafunction `result<A1, ... AN>` that takes the types of the `N` arguments to
|
|
the function and returns the result type of the function. (There is a special case for function
|
|
objects that accept no arguments. Such nullary functors are only required to define a typedef
|
|
`result_type` that reflects the return type of its `operator()`).
|
|
]
|
|
|
|
For example, the following type implements the FunctionEval concept, in order to provide a
|
|
lazy factorial function:
|
|
|
|
struct factorial_impl
|
|
{
|
|
template <typename Sig>
|
|
struct result;
|
|
|
|
template <typename This, typename Arg>
|
|
struct result<This(Arg)>
|
|
: typedef boost::remove_reference<Arg>
|
|
{};
|
|
|
|
template <typename Arg>
|
|
Arg operator()(Arg n) const
|
|
{
|
|
return (n <= 0) ? 1 : n * this->operator()(n-1);
|
|
}
|
|
};
|
|
|
|
(See [@../../example/users_manual/factorial.cpp factorial.cpp])
|
|
|
|
[note The type of Arg is either a const-reference or non-const-reference
|
|
(depending on wether your argument to the actor evaluation is a const-ref or
|
|
non-const-ref).]
|
|
|
|
Having implemented the `factorial_impl` type, we can declare and instantiate a lazy
|
|
`factorial` function this way:
|
|
|
|
function<factorial_impl> factorial;
|
|
|
|
Invoking a lazy function such as `factorial` does not immediately execute the function
|
|
object `factorial_impl`. Instead, an [link phoenix.reference.actor `actor`] object is
|
|
created and returned to the caller. Example:
|
|
|
|
factorial(arg1)
|
|
|
|
does nothing more than return an actor. A second function call will invoke
|
|
the actual factorial function. Example:
|
|
|
|
cout << factorial(arg1)(4);
|
|
|
|
will print out "24".
|
|
|
|
Take note that in certain cases (e.g. for function objects with state), an
|
|
instance of the model of FunctionEval may be passed on to the constructor. Example:
|
|
|
|
function<factorial_impl> factorial(ftor);
|
|
|
|
where ftor is an instance of factorial_impl (this is not necessary in this case
|
|
as `factorial_impl` does not require any state).
|
|
|
|
[blurb __alert__ Take care though when using function objects with state because they are
|
|
often copied repeatedly, and state may change in one of the copies, rather than the
|
|
original.]
|
|
|
|
[endsect]
|