diff options
Diffstat (limited to 'doc/html/lambda')
-rw-r--r-- | doc/html/lambda/extending.html | 421 | ||||
-rw-r--r-- | doc/html/lambda/getting_started.html | 102 | ||||
-rw-r--r-- | doc/html/lambda/le_in_details.html | 1614 | ||||
-rw-r--r-- | doc/html/lambda/s03.html | 264 | ||||
-rw-r--r-- | doc/html/lambda/s07.html | 314 | ||||
-rw-r--r-- | doc/html/lambda/s08.html | 177 | ||||
-rw-r--r-- | doc/html/lambda/s09.html | 45 | ||||
-rw-r--r-- | doc/html/lambda/using_library.html | 310 |
8 files changed, 3247 insertions, 0 deletions
diff --git a/doc/html/lambda/extending.html b/doc/html/lambda/extending.html new file mode 100644 index 0000000000..d7780d4ba6 --- /dev/null +++ b/doc/html/lambda/extending.html @@ -0,0 +1,421 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Extending return type deduction system</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="le_in_details.html" title="Lambda expressions in details"> +<link rel="next" href="s07.html" title="Practical considerations"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="le_in_details.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s07.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="lambda.extending"></a>Extending return type deduction system</h3></div></div></div> +<p> + +In this section, we explain how to extend the return type deduction system +to cover user defined operators. + +In many cases this is not necessary, +as the BLL defines default return types for operators. + +For example, the default return type for all comparison operators is +<code class="literal">bool</code>, and as long as the user defined comparison operators +have a bool return type, there is no need to write new specializations +for the return type deduction classes. + +Sometimes this cannot be avoided, though. + +</p> +<p> +The overloadable user defined operators are either unary or binary. + +For each arity, there are two traits templates that define the +return types of the different operators. + +Hence, the return type system can be extended by providing more +specializations for these templates. + +The templates for unary functors are + +<code class="literal"> +plain_return_type_1<Action, A> +</code> + +and + +<code class="literal"> +return_type_1<Action, A> +</code>, and + +<code class="literal"> +plain_return_type_2<Action, A, B> +</code> + +and + +<code class="literal"> +return_type_2<Action, A, B> +</code> + +respectively for binary functors. + +</p> +<p> +The first parameter (<code class="literal">Action</code>) to all these templates +is the <span class="emphasis"><em>action</em></span> class, which specifies the operator. + +Operators with similar return type rules are grouped together into +<span class="emphasis"><em>action groups</em></span>, +and only the action class and action group together define the operator +unambiguously. + +As an example, the action type +<code class="literal">arithmetic_action<plus_action></code> stands for +<code class="literal">operator+</code>. + +The complete listing of different action types is shown in +<a href="extending.html#table:actions" title="Table 6.2. Action types">Table 6.2, “Action types”</a>. +</p> +<p> +The latter parameters, <code class="literal">A</code> in the unary case, +or <code class="literal">A</code> and <code class="literal">B</code> in the binary case, +stand for the argument types of the operator call. + +The two sets of templates, +<code class="literal">plain_return_type_<em class="parameter"><code>n</code></em></code> and +<code class="literal">return_type_<em class="parameter"><code>n</code></em></code> +(<em class="parameter"><code>n</code></em> is 1 or 2) differ in the way how parameter types +are presented to them. + +For the former templates, the parameter types are always provided as +non-reference types, and do not have const or volatile qualifiers. + +This makes specializing easy, as commonly one specialization for each +user defined operator, or operator group, is enough. + +On the other hand, if a particular operator is overloaded for different +cv-qualifications of the same argument types, +and the return types of these overloaded versions differ, a more fine-grained control is needed. + +Hence, for the latter templates, the parameter types preserve the +cv-qualifiers, and are non-reference types as well. + +The downside is, that for an overloaded set of operators of the +kind described above, one may end up needing up to +16 <code class="literal">return_type_2</code> specializations. +</p> +<p> +Suppose the user has overloaded the following operators for some user defined +types <code class="literal">X</code>, <code class="literal">Y</code> and <code class="literal">Z</code>: + +</p> +<pre class="programlisting"> +Z operator+(const X&, const Y&); +Z operator-(const X&, const Y&); +</pre> +<p> + +Now, one can add a specialization stating, that if the left hand argument +is of type <code class="literal">X</code>, and the right hand one of type +<code class="literal">Y</code>, the return type of all such binary arithmetic +operators is <code class="literal">Z</code>: + +</p> +<pre class="programlisting"> +namespace boost { +namespace lambda { + +template<class Act> +struct plain_return_type_2<arithmetic_action<Act>, X, Y> { + typedef Z type; +}; + +} +} +</pre> +<p> + +Having this specialization defined, BLL is capable of correctly +deducing the return type of the above two operators. + +Note, that the specializations must be in the same namespace, +<code class="literal">::boost::lambda</code>, with the primary template. + +For brevity, we do not show the namespace definitions in the examples below. +</p> +<p> +It is possible to specialize on the level of an individual operator as well, +in addition to providing a specialization for a group of operators. +Say, we add a new arithmetic operator for argument types <code class="literal">X</code> +and <code class="literal">Y</code>: + +</p> +<pre class="programlisting"> +X operator*(const X&, const Y&); +</pre> +<p> + +Our first rule for all arithmetic operators specifies that the return +type of this operator is <code class="literal">Z</code>, +which obviously is not the case. +Hence, we provide a new rule for the multiplication operator: + +</p> +<pre class="programlisting"> +template<> +struct plain_return_type_2<arithmetic_action<multiply_action>, X, Y> { + typedef X type; +}; +</pre> +<p> +The specializations can define arbitrary mappings from the argument types +to the return type. + +Suppose we have some mathematical vector type, templated on the element type: + +</p> +<pre class="programlisting"> +template <class T> class my_vector; +</pre> +<p> + +Suppose the addition operator is defined between any two +<code class="literal">my_vector</code> instantiations, +as long as the addition operator is defined between their element types. + +Furthermore, the element type of the resulting <code class="literal">my_vector</code> +is the same as the result type of the addition between the element types. + +E.g., adding <code class="literal">my_vector<int></code> and +<code class="literal">my_vector<double></code> results in +<code class="literal">my_vector<double></code>. + +The BLL has traits classes to perform the implicit built-in and standard +type conversions between integral, floating point, and complex classes. + +Using BLL tools, the addition operator described above can be defined as: + +</p> +<pre class="programlisting"> +template<class A, class B> +my_vector<typename return_type_2<arithmetic_action<plus_action>, A, B>::type> +operator+(const my_vector<A>& a, const my_vector<B>& b) +{ + typedef typename + return_type_2<arithmetic_action<plus_action>, A, B>::type res_type; + return my_vector<res_type>(); +} +</pre> +<p> +To allow BLL to deduce the type of <code class="literal">my_vector</code> +additions correctly, we can define: + +</p> +<pre class="programlisting"> +template<class A, class B> +class plain_return_type_2<arithmetic_action<plus_action>, + my_vector<A>, my_vector<B> > { + typedef typename + return_type_2<arithmetic_action<plus_action>, A, B>::type res_type; +public: + typedef my_vector<res_type> type; +}; +</pre> +<p> +Note, that we are reusing the existing specializations for the +BLL <code class="literal">return_type_2</code> template, +which require that the argument types are references. +</p> +<div class="table"> +<a name="table:actions"></a><p class="title"><b>Table 6.2. Action types</b></p> +<table class="table" summary="Action types"> +<colgroup> +<col> +<col> +</colgroup> +<tbody> +<tr> +<td><code class="literal">+</code></td> +<td><code class="literal">arithmetic_action<plus_action></code></td> +</tr> +<tr> +<td><code class="literal">-</code></td> +<td><code class="literal">arithmetic_action<minus_action></code></td> +</tr> +<tr> +<td><code class="literal">*</code></td> +<td><code class="literal">arithmetic_action<multiply_action></code></td> +</tr> +<tr> +<td><code class="literal">/</code></td> +<td><code class="literal">arithmetic_action<divide_action></code></td> +</tr> +<tr> +<td><code class="literal">%</code></td> +<td><code class="literal">arithmetic_action<remainder_action></code></td> +</tr> +<tr> +<td><code class="literal">+</code></td> +<td><code class="literal">unary_arithmetic_action<plus_action></code></td> +</tr> +<tr> +<td><code class="literal">-</code></td> +<td><code class="literal">unary_arithmetic_action<minus_action></code></td> +</tr> +<tr> +<td><code class="literal">&</code></td> +<td><code class="literal">bitwise_action<and_action></code></td> +</tr> +<tr> +<td><code class="literal">|</code></td> +<td><code class="literal">bitwise_action<or_action></code></td> +</tr> +<tr> +<td><code class="literal">~</code></td> +<td><code class="literal">bitwise_action<not_action></code></td> +</tr> +<tr> +<td><code class="literal">^</code></td> +<td><code class="literal">bitwise_action<xor_action></code></td> +</tr> +<tr> +<td><code class="literal"><<</code></td> +<td><code class="literal">bitwise_action<leftshift_action_no_stream></code></td> +</tr> +<tr> +<td><code class="literal">>></code></td> +<td><code class="literal">bitwise_action<rightshift_action_no_stream></code></td> +</tr> +<tr> +<td><code class="literal">&&</code></td> +<td><code class="literal">logical_action<and_action></code></td> +</tr> +<tr> +<td><code class="literal">||</code></td> +<td><code class="literal">logical_action<or_action></code></td> +</tr> +<tr> +<td><code class="literal">!</code></td> +<td><code class="literal">logical_action<not_action></code></td> +</tr> +<tr> +<td><code class="literal"><</code></td> +<td><code class="literal">relational_action<less_action></code></td> +</tr> +<tr> +<td><code class="literal">></code></td> +<td><code class="literal">relational_action<greater_action></code></td> +</tr> +<tr> +<td><code class="literal"><=</code></td> +<td><code class="literal">relational_action<lessorequal_action></code></td> +</tr> +<tr> +<td><code class="literal">>=</code></td> +<td><code class="literal">relational_action<greaterorequal_action></code></td> +</tr> +<tr> +<td><code class="literal">==</code></td> +<td><code class="literal">relational_action<equal_action></code></td> +</tr> +<tr> +<td><code class="literal">!=</code></td> +<td><code class="literal">relational_action<notequal_action></code></td> +</tr> +<tr> +<td><code class="literal">+=</code></td> +<td><code class="literal">arithmetic_assignment_action<plus_action></code></td> +</tr> +<tr> +<td><code class="literal">-=</code></td> +<td><code class="literal">arithmetic_assignment_action<minus_action></code></td> +</tr> +<tr> +<td><code class="literal">*=</code></td> +<td><code class="literal">arithmetic_assignment_action<multiply_action></code></td> +</tr> +<tr> +<td><code class="literal">/=</code></td> +<td><code class="literal">arithmetic_assignment_action<divide_action></code></td> +</tr> +<tr> +<td><code class="literal">%=</code></td> +<td><code class="literal">arithmetic_assignment_action<remainder_action></code></td> +</tr> +<tr> +<td><code class="literal">&=</code></td> +<td><code class="literal">bitwise_assignment_action<and_action></code></td> +</tr> +<tr> +<td><code class="literal">=|</code></td> +<td><code class="literal">bitwise_assignment_action<or_action></code></td> +</tr> +<tr> +<td><code class="literal">^=</code></td> +<td><code class="literal">bitwise_assignment_action<xor_action></code></td> +</tr> +<tr> +<td><code class="literal"><<=</code></td> +<td><code class="literal">bitwise_assignment_action<leftshift_action></code></td> +</tr> +<tr> +<td><code class="literal">>>=</code></td> +<td><code class="literal">bitwise_assignment_action<rightshift_action></code></td> +</tr> +<tr> +<td><code class="literal">++</code></td> +<td><code class="literal">pre_increment_decrement_action<increment_action></code></td> +</tr> +<tr> +<td><code class="literal">--</code></td> +<td><code class="literal">pre_increment_decrement_action<decrement_action></code></td> +</tr> +<tr> +<td><code class="literal">++</code></td> +<td><code class="literal">post_increment_decrement_action<increment_action></code></td> +</tr> +<tr> +<td><code class="literal">--</code></td> +<td><code class="literal">post_increment_decrement_action<decrement_action></code></td> +</tr> +<tr> +<td><code class="literal">&</code></td> +<td><code class="literal">other_action<address_of_action></code></td> +</tr> +<tr> +<td><code class="literal">*</code></td> +<td><code class="literal">other_action<contents_of_action></code></td> +</tr> +<tr> +<td><code class="literal">,</code></td> +<td><code class="literal">other_action<comma_action></code></td> +</tr> +</tbody> +</table> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="le_in_details.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s07.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/lambda/getting_started.html b/doc/html/lambda/getting_started.html new file mode 100644 index 0000000000..d7007eb21b --- /dev/null +++ b/doc/html/lambda/getting_started.html @@ -0,0 +1,102 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Getting Started</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="next" href="s03.html" title="Introduction"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../lambda.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s03.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="lambda.getting_started"></a>Getting Started</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="getting_started.html#id1222408">Installing the library</a></span></dt> +<dt><span class="section"><a href="getting_started.html#id1222668">Conventions used in this document</a></span></dt> +</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1222408"></a>Installing the library</h4></div></div></div> +<p> + The library consists of include files only, hence there is no + installation procedure. The <code class="literal">boost</code> include directory + must be on the include path. + There are a number of include files that give different functionality: + + </p> +<div class="itemizedlist"><ul type="disc"> +<li><p><code class="filename">lambda/lambda.hpp</code> defines lambda expressions for different C++ + operators, see <a href="le_in_details.html#lambda.operator_expressions" title="Operator expressions">the section called “Operator expressions”</a>. + </p></li> +<li><p><code class="filename">lambda/bind.hpp</code> defines <code class="literal">bind</code> functions for up to 9 arguments, see <a href="le_in_details.html#lambda.bind_expressions" title="Bind expressions">the section called “Bind expressions”</a>.</p></li> +<li><p><code class="filename">lambda/if.hpp</code> defines lambda function equivalents for if statements and the conditional operator, see <a href="le_in_details.html#lambda.lambda_expressions_for_control_structures" title="Lambda expressions for control structures">the section called “Lambda expressions for control structures”</a> (includes <code class="filename">lambda.hpp</code>). + </p></li> +<li><p><code class="filename">lambda/loops.hpp</code> defines lambda function equivalent for looping constructs, see <a href="le_in_details.html#lambda.lambda_expressions_for_control_structures" title="Lambda expressions for control structures">the section called “Lambda expressions for control structures”</a>. + </p></li> +<li><p><code class="filename">lambda/switch.hpp</code> defines lambda function equivalent for the switch statement, see <a href="le_in_details.html#lambda.lambda_expressions_for_control_structures" title="Lambda expressions for control structures">the section called “Lambda expressions for control structures”</a>. + </p></li> +<li><p><code class="filename">lambda/construct.hpp</code> provides tools for writing lambda expressions with constructor, destructor, new and delete invocations, see <a href="le_in_details.html#lambda.construction_and_destruction" title="Construction and destruction">the section called “Construction and destruction”</a> (includes <code class="filename">lambda.hpp</code>). + </p></li> +<li><p><code class="filename">lambda/casts.hpp</code> provides lambda versions of different casts, as well as <code class="literal">sizeof</code> and <code class="literal">typeid</code>, see <a href="le_in_details.html#lambda.cast_expressions" title=" +Cast expressions +">the section called “ +Cast expressions +”</a>. + </p></li> +<li><p><code class="filename">lambda/exceptions.hpp</code> gives tools for throwing and catching + exceptions within lambda functions, <a href="le_in_details.html#lambda.exceptions" title="Exceptions">the section called “Exceptions”</a> (includes + <code class="filename">lambda.hpp</code>). + </p></li> +<li><p><code class="filename">lambda/algorithm.hpp</code> and <code class="filename">lambda/numeric.hpp</code> (cf. standard <code class="filename">algortihm</code> and <code class="filename">numeric</code> headers) allow nested STL algorithm invocations, see <a href="le_in_details.html#lambda.nested_stl_algorithms" title="Nesting STL algorithm invocations">the section called “Nesting STL algorithm invocations”</a>. + </p></li> +</ul></div> +<p> + + Any other header files in the package are for internal use. + Additionally, the library depends on two other Boost Libraries, the + <span class="emphasis"><em>Tuple</em></span>[<a href="../lambda.html#cit:boost::tuple" title="[tuple]"><span class="abbrev">tuple</span></a>] and the <span class="emphasis"><em>type_traits</em></span>[<a href="../lambda.html#cit:boost::type_traits" title="[type_traits]"><span class="abbrev">type_traits</span></a>] libraries, and on the <code class="filename">boost/ref.hpp</code> header. + </p> +<p> + All definitions are placed in the namespace <code class="literal">boost::lambda</code> and its subnamespaces. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1222668"></a>Conventions used in this document</h4></div></div></div> +<p>In most code examples, we omit the namespace prefixes for names in the <code class="literal">std</code> and <code class="literal">boost::lambda</code> namespaces. +Implicit using declarations +</p> +<pre class="programlisting"> +using namespace std; +using namespace boost::lambda; +</pre> +<p> +are assumed to be in effect. +</p> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="../lambda.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s03.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/lambda/le_in_details.html b/doc/html/lambda/le_in_details.html new file mode 100644 index 0000000000..18ac108c5e --- /dev/null +++ b/doc/html/lambda/le_in_details.html @@ -0,0 +1,1614 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Lambda expressions in details</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="using_library.html" title="Using the library"> +<link rel="next" href="extending.html" title="Extending return type deduction system"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="using_library.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="extending.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="lambda.le_in_details"></a>Lambda expressions in details</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="le_in_details.html#lambda.placeholders">Placeholders</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.operator_expressions">Operator expressions</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.bind_expressions">Bind expressions</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.overriding_deduced_return_type">Overriding the deduced return type</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.delaying_constants_and_variables">Delaying constants and variables</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.lambda_expressions_for_control_structures">Lambda expressions for control structures</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.exceptions">Exceptions</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.construction_and_destruction">Construction and destruction</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#id1243846">Special lambda expressions</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#id1244283">Casts, sizeof and typeid</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.nested_stl_algorithms">Nesting STL algorithm invocations</a></span></dt> +</dl></div> +<p> +This section describes different categories of lambda expressions in details. +We devote a separate section for each of the possible forms of a lambda expression. + + +</p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.placeholders"></a>Placeholders</h4></div></div></div> +<p> +The BLL defines three placeholder types: <code class="literal">placeholder1_type</code>, <code class="literal">placeholder2_type</code> and <code class="literal">placeholder3_type</code>. +BLL has a predefined placeholder variable for each placeholder type: <code class="literal">_1</code>, <code class="literal">_2</code> and <code class="literal">_3</code>. +However, the user is not forced to use these placeholders. +It is easy to define placeholders with alternative names. +This is done by defining new variables of placeholder types. +For example: + +</p> +<pre class="programlisting">boost::lambda::placeholder1_type X; +boost::lambda::placeholder2_type Y; +boost::lambda::placeholder3_type Z; +</pre> +<p> + +With these variables defined, <code class="literal">X += Y * Z</code> is equivalent to <code class="literal">_1 += _2 * _3</code>. +</p> +<p> +The use of placeholders in the lambda expression determines whether the resulting function is nullary, unary, binary or 3-ary. +The highest placeholder index is decisive. For example: + +</p> +<pre class="programlisting"> +_1 + 5 // unary +_1 * _1 + _1 // unary +_1 + _2 // binary +bind(f, _1, _2, _3) // 3-ary +_3 + 10 // 3-ary +</pre> +<p> + +Note that the last line creates a 3-ary function, which adds <code class="literal">10</code> to its <span class="emphasis"><em>third</em></span> argument. +The first two arguments are discarded. +Furthermore, lambda functors only have a minimum arity. +One can always provide more arguments (up the number of supported placeholders) +that is really needed. +The remaining arguments are just discarded. +For example: + +</p> +<pre class="programlisting"> +int i, j, k; +_1(i, j, k) // returns i, discards j and k +(_2 + _2)(i, j, k) // returns j+j, discards i and k +</pre> +<p> + +See +<a href="../apa.html#lambda.why_weak_arity" title=" +Lambda functor arity +">the section called “ +Lambda functor arity +”</a> for the design rationale behind this +functionality. + +</p> +<p> +In addition to these three placeholder types, there is also a fourth placeholder type <code class="literal">placeholderE_type</code>. +The use of this placeholder is defined in <a href="le_in_details.html#lambda.exceptions" title="Exceptions">the section called “Exceptions”</a> describing exception handling in lambda expressions. +</p> +<p>When an actual argument is supplied for a placeholder, the parameter passing mode is always by reference. +This means that any side-effects to the placeholder are reflected to the actual argument. +For example: + + +</p> +<pre class="programlisting"> +int i = 1; +(_1 += 2)(i); // i is now 3 +(++_1, cout << _1)(i) // i is now 4, outputs 4 +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.operator_expressions"></a>Operator expressions</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="le_in_details.html#id1241496">Operators that cannot be overloaded</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.assignment_and_subscript">Assignment and subscript operators</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.logical_operators">Logical operators</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.comma_operator">Comma operator</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.function_call_operator">Function call operator</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.member_pointer_operator">Member pointer operator</a></span></dt> +</dl></div> +<p> +The basic rule is that any C++ operator invocation with at least one argument being a lambda expression is itself a lambda expression. +Almost all overloadable operators are supported. +For example, the following is a valid lambda expression: + +</p> +<pre class="programlisting">cout << _1, _2[_3] = _1 && false</pre> +<p> +However, there are some restrictions that originate from the C++ operator overloading rules, and some special cases. +</p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="id1241496"></a>Operators that cannot be overloaded</h5></div></div></div> +<p> +Some operators cannot be overloaded at all (<code class="literal">::</code>, <code class="literal">.</code>, <code class="literal">.*</code>). +For some operators, the requirements on return types prevent them to be overloaded to create lambda functors. +These operators are <code class="literal">->.</code>, <code class="literal">-></code>, <code class="literal">new</code>, <code class="literal">new[]</code>, <code class="literal">delete</code>, <code class="literal">delete[]</code> and <code class="literal">?:</code> (the conditional operator). +</p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.assignment_and_subscript"></a>Assignment and subscript operators</h5></div></div></div> +<p> +These operators must be implemented as class members. +Consequently, the left operand must be a lambda expression. For example: + +</p> +<pre class="programlisting"> +int i; +_1 = i; // ok +i = _1; // not ok. i is not a lambda expression +</pre> +<p> + +There is a simple solution around this limitation, described in <a href="le_in_details.html#lambda.delaying_constants_and_variables" title="Delaying constants and variables">the section called “Delaying constants and variables”</a>. +In short, +the left hand argument can be explicitly turned into a lambda functor by wrapping it with a special <code class="literal">var</code> function: +</p> +<pre class="programlisting"> +var(i) = _1; // ok +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.logical_operators"></a>Logical operators</h5></div></div></div> +<p> +Logical operators obey the short-circuiting evaluation rules. For example, in the following code, <code class="literal">i</code> is never incremented: +</p> +<pre class="programlisting"> +bool flag = true; int i = 0; +(_1 || ++_2)(flag, i); +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.comma_operator"></a>Comma operator</h5></div></div></div> +<p> +Comma operator is the “<span class="quote">statement separator</span>” in lambda expressions. +Since comma is also the separator between arguments in a function call, extra parenthesis are sometimes needed: + +</p> +<pre class="programlisting"> +for_each(a.begin(), a.end(), (++_1, cout << _1)); +</pre> +<p> + +Without the extra parenthesis around <code class="literal">++_1, cout << _1</code>, the code would be interpreted as an attempt to call <code class="literal">for_each</code> with four arguments. +</p> +<p> +The lambda functor created by the comma operator adheres to the C++ rule of always evaluating the left operand before the right one. +In the above example, each element of <code class="literal">a</code> is first incremented, then written to the stream. +</p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.function_call_operator"></a>Function call operator</h5></div></div></div> +<p> +The function call operators have the effect of evaluating the lambda +functor. +Calls with too few arguments lead to a compile time error. +</p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.member_pointer_operator"></a>Member pointer operator</h5></div></div></div> +<p> +The member pointer operator <code class="literal">operator->*</code> can be overloaded freely. +Hence, for user defined types, member pointer operator is no special case. +The built-in meaning, however, is a somewhat more complicated case. +The built-in member pointer operator is applied if the left argument is a pointer to an object of some class <code class="literal">A</code>, and the right hand argument is a pointer to a member of <code class="literal">A</code>, or a pointer to a member of a class from which <code class="literal">A</code> derives. +We must separate two cases: + +</p> +<div class="itemizedlist"><ul type="disc"> +<li> +<p>The right hand argument is a pointer to a data member. +In this case the lambda functor simply performs the argument substitution and calls the built-in member pointer operator, which returns a reference to the member pointed to. +For example: +</p> +<pre class="programlisting"> +struct A { int d; }; +A* a = new A(); + ... +(a ->* &A::d); // returns a reference to a->d +(_1 ->* &A::d)(a); // likewise +</pre> +</li> +<li> +<p> +The right hand argument is a pointer to a member function. +For a built-in call like this, the result is kind of a delayed member function call. +Such an expression must be followed by a function argument list, with which the delayed member function call is performed. +For example: +</p> +<pre class="programlisting"> +struct B { int foo(int); }; +B* b = new B(); + ... +(b ->* &B::foo) // returns a delayed call to b->foo + // a function argument list must follow +(b ->* &B::foo)(1) // ok, calls b->foo(1) + +(_1 ->* &B::foo)(b); // returns a delayed call to b->foo, + // no effect as such +(_1 ->* &B::foo)(b)(1); // calls b->foo(1) +</pre> +</li> +</ul></div> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.bind_expressions"></a>Bind expressions</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="le_in_details.html#lambda.function_pointers_as_targets">Function pointers or references as targets</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#member_functions_as_targets">Member functions as targets</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.members_variables_as_targets">Member variables as targets</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.function_objects_as_targets">Function objects as targets</a></span></dt> +</dl></div> +<p> +Bind expressions can have two forms: + +</p> +<pre class="programlisting"> +bind(<em class="parameter"><code>target-function</code></em>, <em class="parameter"><code>bind-argument-list</code></em>) +bind(<em class="parameter"><code>target-member-function</code></em>, <em class="parameter"><code>object-argument</code></em>, <em class="parameter"><code>bind-argument-list</code></em>) +</pre> +<p> + +A bind expression delays the call of a function. +If this <span class="emphasis"><em>target function</em></span> is <span class="emphasis"><em>n</em></span>-ary, then the <code class="literal"><span class="emphasis"><em>bind-argument-list</em></span></code> must contain <span class="emphasis"><em>n</em></span> arguments as well. +In the current version of the BLL, 0 <= n <= 9 must hold. +For member functions, the number of arguments must be at most 8, as the object argument takes one argument position. + +Basically, the +<span class="emphasis"><em><code class="literal">bind-argument-list</code></em></span> must be a valid argument list for the target function, except that any argument can be replaced with a placeholder, or more generally, with a lambda expression. +Note that also the target function can be a lambda expression. + +The result of a bind expression is either a nullary, unary, binary or 3-ary function object depending on the use of placeholders in the <span class="emphasis"><em><code class="literal">bind-argument-list</code></em></span> (see <a href="le_in_details.html#lambda.placeholders" title="Placeholders">the section called “Placeholders”</a>). +</p> +<p> +The return type of the lambda functor created by the bind expression can be given as an explicitly specified template parameter, as in the following example: +</p> +<pre class="programlisting"> +bind<<span class="emphasis"><em>RET</em></span>>(<span class="emphasis"><em>target-function</em></span>, <span class="emphasis"><em>bind-argument-list</em></span>) +</pre> +<p> +This is only necessary if the return type of the target function cannot be deduced. +</p> +<p> +The following sections describe the different types of bind expressions. +</p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.function_pointers_as_targets"></a>Function pointers or references as targets</h5></div></div></div> +<p>The target function can be a pointer or a reference to a function and it can be either bound or unbound. For example: +</p> +<pre class="programlisting"> +X foo(A, B, C); A a; B b; C c; +bind(foo, _1, _2, c)(a, b); +bind(&foo, _1, _2, c)(a, b); +bind(_1, a, b, c)(foo); +</pre> +<p> + +The return type deduction always succeeds with this type of bind expressions. +</p> +<p> +Note, that in C++ it is possible to take the address of an overloaded function only if the address is assigned to, or used as an initializer of, a variable, the type of which solves the amibiguity, or if an explicit cast expression is used. +This means that overloaded functions cannot be used in bind expressions directly, e.g.: +</p> +<pre class="programlisting"> +void foo(int); +void foo(float); +int i; + ... +bind(&foo, _1)(i); // error + ... +void (*pf1)(int) = &foo; +bind(pf1, _1)(i); // ok +bind(static_cast<void(*)(int)>(&foo), _1)(i); // ok +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="member_functions_as_targets"></a>Member functions as targets</h5></div></div></div> +<p> +The syntax for using pointers to member function in bind expression is: +</p> +<pre class="programlisting"> +bind(<em class="parameter"><code>target-member-function</code></em>, <em class="parameter"><code>object-argument</code></em>, <em class="parameter"><code>bind-argument-list</code></em>) +</pre> +<p> + +The object argument can be a reference or pointer to the object, the BLL supports both cases with a uniform interface: + +</p> +<pre class="programlisting"> +bool A::foo(int) const; +A a; +vector<int> ints; + ... +find_if(ints.begin(), ints.end(), bind(&A::foo, a, _1)); +find_if(ints.begin(), ints.end(), bind(&A::foo, &a, _1)); +</pre> +<p> + +Similarly, if the object argument is unbound, the resulting lambda functor can be called both via a pointer or a reference: + +</p> +<pre class="programlisting"> +bool A::foo(int); +list<A> refs; +list<A*> pointers; + ... +find_if(refs.begin(), refs.end(), bind(&A::foo, _1, 1)); +find_if(pointers.begin(), pointers.end(), bind(&A::foo, _1, 1)); +</pre> +<p> +Even though the interfaces are the same, there are important semantic differences between using a pointer or a reference as the object argument. +The differences stem from the way <code class="literal">bind</code>-functions take their parameters, and how the bound parameters are stored within the lambda functor. +The object argument has the same parameter passing and storing mechanism as any other bind argument slot (see <a href="using_library.html#lambda.storing_bound_arguments" title="Storing bound arguments in lambda functions">the section called “Storing bound arguments in lambda functions”</a>); it is passed as a const reference and stored as a const copy in the lambda functor. +This creates some asymmetry between the lambda functor and the original member function, and between seemingly similar lambda functors. For example: +</p> +<pre class="programlisting"> +class A { + int i; mutable int j; +public: + + A(int ii, int jj) : i(ii), j(jj) {}; + void set_i(int x) { i = x; }; + void set_j(int x) const { j = x; }; +}; +</pre> +<p> + +When a pointer is used, the behavior is what the programmer might expect: + +</p> +<pre class="programlisting"> +A a(0,0); int k = 1; +bind(&A::set_i, &a, _1)(k); // a.i == 1 +bind(&A::set_j, &a, _1)(k); // a.j == 1 +</pre> +<p> + +Even though a const copy of the object argument is stored, the original object <code class="literal">a</code> is still modified. +This is since the object argument is a pointer, and the pointer is copied, not the object it points to. +When we use a reference, the behaviour is different: + +</p> +<pre class="programlisting"> +A a(0,0); int k = 1; +bind(&A::set_i, a, _1)(k); // error; a const copy of a is stored. + // Cannot call a non-const function set_i +bind(&A::set_j, a, _1)(k); // a.j == 0, as a copy of a is modified +</pre> +<p> +To prevent the copying from taking place, one can use the <code class="literal">ref</code> or <code class="literal">cref</code> wrappers (<code class="literal">var</code> and <code class="literal">constant_ref</code> would do as well): +</p> +<pre class="programlisting"> +bind(&A::set_i, ref(a), _1)(k); // a.j == 1 +bind(&A::set_j, cref(a), _1)(k); // a.j == 1 +</pre> +<p>Note that the preceding discussion is relevant only for bound arguments. +If the object argument is unbound, the parameter passing mode is always by reference. +Hence, the argument <code class="literal">a</code> is not copied in the calls to the two lambda functors below: +</p> +<pre class="programlisting"> +A a(0,0); +bind(&A::set_i, _1, 1)(a); // a.i == 1 +bind(&A::set_j, _1, 1)(a); // a.j == 1 +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.members_variables_as_targets"></a>Member variables as targets</h5></div></div></div> +<p> +A pointer to a member variable is not really a function, but +the first argument to the <code class="literal">bind</code> function can nevertheless +be a pointer to a member variable. +Invoking such a bind expression returns a reference to the data member. +For example: + +</p> +<pre class="programlisting"> +struct A { int data; }; +A a; +bind(&A::data, _1)(a) = 1; // a.data == 1 +</pre> +<p> + +The cv-qualifiers of the object whose member is accessed are respected. +For example, the following tries to write into a const location: +</p> +<pre class="programlisting"> +const A ca = a; +bind(&A::data, _1)(ca) = 1; // error +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.function_objects_as_targets"></a>Function objects as targets</h5></div></div></div> +<p> + +Function objects, that is, class objects which have the function call +operator defined, can be used as target functions. + +In general, BLL cannot deduce the return type of an arbitrary function object. + +However, there are two methods for giving BLL this capability for a certain +function object class. + +</p> +<div class="simplesect" lang="en"> +<div class="titlepage"><div><div><h6 class="title"> +<a name="id1242153"></a>The result_type typedef</h6></div></div></div> +<p> + +The BLL supports the standard library convention of declaring the return type +of a function object with a member typedef named <code class="literal">result_type</code> in the +function object class. + +Here is a simple example: +</p> +<pre class="programlisting"> +struct A { + typedef B result_type; + B operator()(X, Y, Z); +}; +</pre> +<p> + +If a function object does not define a <code class="literal">result_type</code> typedef, +the method described below (<code class="literal">sig</code> template) +is attempted to resolve the return type of the +function object. If a function object defines both <code class="literal">result_type</code> +and <code class="literal">sig</code>, <code class="literal">result_type</code> takes precedence. + +</p> +</div> +<div class="simplesect" lang="en"> +<div class="titlepage"><div><div><h6 class="title"> +<a name="id1242206"></a>The sig template</h6></div></div></div> +<p> +Another mechanism that make BLL aware of the return type(s) of a function object is defining +member template struct +<code class="literal">sig<Args></code> with a typedef +<code class="literal">type</code> that specifies the return type. + +Here is a simple example: +</p> +<pre class="programlisting"> +struct A { + template <class Args> struct sig { typedef B type; } + B operator()(X, Y, Z); +}; +</pre> +<p> + +The template argument <code class="literal">Args</code> is a +<code class="literal">tuple</code> (or more precisely a <code class="literal">cons</code> list) +type [<a href="../lambda.html#cit:boost::tuple" title="[tuple]"><span class="abbrev">tuple</span></a>], where the first element +is the function +object type itself, and the remaining elements are the types of +the arguments, with which the function object is being called. + +This may seem overly complex compared to defining the <code class="literal">result_type</code> typedef. +Howver, there are two significant restrictions with using just a simple +typedef to express the return type: +</p> +<div class="orderedlist"><ol type="1"> +<li><p> +If the function object defines several function call operators, there is no way to specify different result types for them. +</p></li> +<li><p> +If the function call operator is a template, the result type may +depend on the template parameters. +Hence, the typedef ought to be a template too, which the C++ language +does not support. +</p></li> +</ol></div> +<p> + +The following code shows an example, where the return type depends on the type +of one of the arguments, and how that dependency can be expressed with the +<code class="literal">sig</code> template: + +</p> +<pre class="programlisting"> +struct A { + + // the return type equals the third argument type: + template<class T1, class T2, class T3> + T3 operator()(const T1& t1, const T2& t2, const T3& t3) const; + + template <class Args> + class sig { + // get the third argument type (4th element) + typedef typename + boost::tuples::element<3, Args>::type T3; + public: + typedef typename + boost::remove_cv<T3>::type type; + }; +}; +</pre> +<p> + + +The elements of the <code class="literal">Args</code> tuple are always +non-reference types. + +Moreover, the element types can have a const or volatile qualifier +(jointly referred to as <span class="emphasis"><em>cv-qualifiers</em></span>), or both. +This is since the cv-qualifiers in the arguments can affect the return type. +The reason for including the potentially cv-qualified function object +type itself into the <code class="literal">Args</code> tuple, is that the function +object class can contain both const and non-const (or volatile, even +const volatile) function call operators, and they can each have a different +return type. +</p> +<p> +The <code class="literal">sig</code> template can be seen as a +<span class="emphasis"><em>meta-function</em></span> that maps the argument type tuple to +the result type of the call made with arguments of the types in the tuple. + +As the example above demonstrates, the template can end up being somewhat +complex. +Typical tasks to be performed are the extraction of the relevant types +from the tuple, removing cv-qualifiers etc. +See the Boost type_traits [<a href="../lambda.html#cit:boost::type_traits" title="[type_traits]"><span class="abbrev">type_traits</span></a>] and +Tuple [<a href="../lambda.html#cit:boost::type_traits" title="[type_traits]"><span class="abbrev">type_traits</span></a>] libraries +for tools that can aid in these tasks. +The <code class="literal">sig</code> templates are a refined version of a similar +mechanism first introduced in the FC++ library +[<a href="../lambda.html#cit:fc++" title="[fc++]"><span class="abbrev">fc++</span></a>]. +</p> +</div> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.overriding_deduced_return_type"></a>Overriding the deduced return type</h4></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="le_in_details.html#lambda.nullary_functors_and_ret">Nullary lambda functors and ret</a></span></dt></dl></div> +<p> +The return type deduction system may not be able to deduce the return types of some user defined operators or bind expressions with class objects. + +A special lambda expression type is provided for stating the return type explicitly and overriding the deduction system. +To state that the return type of the lambda functor defined by the lambda expression <code class="literal">e</code> is <code class="literal">T</code>, you can write: + +</p> +<pre class="programlisting">ret<T>(e);</pre> +<p> + +The effect is that the return type deduction is not performed for the lambda expression <code class="literal">e</code> at all, but instead, <code class="literal">T</code> is used as the return type. +Obviously <code class="literal">T</code> cannot be an arbitrary type, the true result of the lambda functor must be implicitly convertible to <code class="literal">T</code>. +For example: + +</p> +<pre class="programlisting"> +A a; B b; +C operator+(A, B); +int operator*(A, B); + ... +ret<D>(_1 + _2)(a, b); // error (C cannot be converted to D) +ret<C>(_1 + _2)(a, b); // ok +ret<float>(_1 * _2)(a, b); // ok (int can be converted to float) + ... +struct X { + Y operator(int)(); +}; + ... +X x; int i; +bind(x, _1)(i); // error, return type cannot be deduced +ret<Y>(bind(x, _1))(i); // ok +</pre> +<p> +For bind expressions, there is a short-hand notation that can be used instead of <code class="literal">ret</code>. +The last line could alternatively be written as: + +</p> +<pre class="programlisting">bind<Z>(x, _1)(i);</pre> +<p> +This feature is modeled after the Boost Bind library [<a href="../lambda.html#cit:boost::bind" title="[bind]"><span class="abbrev">bind</span></a>]. + +</p> +<p>Note that within nested lambda expressions, +the <code class="literal">ret</code> must be used at each subexpression where +the deduction would otherwise fail. +For example: +</p> +<pre class="programlisting"> +A a; B b; +C operator+(A, B); D operator-(C); + ... +ret<D>( - (_1 + _2))(a, b); // error +ret<D>( - ret<C>(_1 + _2))(a, b); // ok +</pre> +<p>If you find yourself using <code class="literal">ret</code> repeatedly with the same types, it is worth while extending the return type deduction (see <a href="extending.html" title="Extending return type deduction system">the section called “Extending return type deduction system”</a>). +</p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.nullary_functors_and_ret"></a>Nullary lambda functors and ret</h5></div></div></div> +<p> +As stated above, the effect of <code class="literal">ret</code> is to prevent the return type deduction to be performed. +However, there is an exception. +Due to the way the C++ template instantiation works, the compiler is always forced to instantiate the return type deduction templates for zero-argument lambda functors. +This introduces a slight problem with <code class="literal">ret</code>, best described with an example: + +</p> +<pre class="programlisting"> +struct F { int operator()(int i) const; }; +F f; + ... +bind(f, _1); // fails, cannot deduce the return type +ret<int>(bind(f, _1)); // ok + ... +bind(f, 1); // fails, cannot deduce the return type +ret<int>(bind(f, 1)); // fails as well! +</pre> +<p> +The BLL cannot deduce the return types of the above bind calls, as <code class="literal">F</code> does not define the typedef <code class="literal">result_type</code>. +One would expect <code class="literal">ret</code> to fix this, but for the nullary lambda functor that results from a bind expression (last line above) this does not work. +The return type deduction templates are instantiated, even though it would not be necessary and the result is a compilation error. +</p> +<p>The solution to this is not to use the <code class="literal">ret</code> function, but rather define the return type as an explicitly specified template parameter in the <code class="literal">bind</code> call: +</p> +<pre class="programlisting"> +bind<int>(f, 1); // ok +</pre> +<p> + +The lambda functors created with +<code class="literal">ret<<em class="parameter"><code>T</code></em>>(bind(<em class="parameter"><code>arg-list</code></em>))</code> and +<code class="literal">bind<<em class="parameter"><code>T</code></em>>(<em class="parameter"><code>arg-list</code></em>)</code> have the exact same functionality — +apart from the fact that for some nullary lambda functors the former does not work while the latter does. +</p> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.delaying_constants_and_variables"></a>Delaying constants and variables</h4></div></div></div> +<p> +The unary functions <code class="literal">constant</code>, +<code class="literal">constant_ref</code> and <code class="literal">var</code> turn their argument into a lambda functor, that implements an identity mapping. +The former two are for constants, the latter for variables. +The use of these <span class="emphasis"><em>delayed</em></span> constants and variables is sometimes necessary due to the lack of explicit syntax for lambda expressions. +For example: +</p> +<pre class="programlisting"> +for_each(a.begin(), a.end(), cout << _1 << ' '); +for_each(a.begin(), a.end(), cout << ' ' << _1); +</pre> +<p> +The first line outputs the elements of <code class="literal">a</code> separated by spaces, while the second line outputs a space followed by the elements of <code class="literal">a</code> without any separators. +The reason for this is that neither of the operands of +<code class="literal">cout << ' '</code> is a lambda expression, hence <code class="literal">cout << ' '</code> is evaluated immediately. + +To delay the evaluation of <code class="literal">cout << ' '</code>, one of the operands must be explicitly marked as a lambda expression. +This is accomplished with the <code class="literal">constant</code> function: +</p> +<pre class="programlisting"> +for_each(a.begin(), a.end(), cout << constant(' ') << _1); +</pre> +<p> + +The call <code class="literal">constant(' ')</code> creates a nullary lambda functor which stores the character constant <code class="literal">' '</code> +and returns a reference to it when invoked. +The function <code class="literal">constant_ref</code> is similar, except that it +stores a constant reference to its argument. + +The <code class="literal">constant</code> and <code class="literal">consant_ref</code> are only +needed when the operator call has side effects, like in the above example. +</p> +<p> +Sometimes we need to delay the evaluation of a variable. +Suppose we wanted to output the elements of a container in a numbered list: + +</p> +<pre class="programlisting"> +int index = 0; +for_each(a.begin(), a.end(), cout << ++index << ':' << _1 << '\n'); +for_each(a.begin(), a.end(), cout << ++var(index) << ':' << _1 << '\n'); +</pre> +<p> + +The first <code class="literal">for_each</code> invocation does not do what we want; <code class="literal">index</code> is incremented only once, and its value is written into the output stream only once. +By using <code class="literal">var</code> to make <code class="literal">index</code> a lambda expression, we get the desired effect. +</p> +<p> +In sum, <code class="literal">var(x)</code> creates a nullary lambda functor, +which stores a reference to the variable <code class="literal">x</code>. +When the lambda functor is invoked, a reference to <code class="literal">x</code> is returned. +</p> +<div class="simplesect" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="id1242806"></a>Naming delayed constants and variables</h5></div></div></div> +<p> +It is possible to predefine and name a delayed variable or constant outside a lambda expression. +The templates <code class="literal">var_type</code>, <code class="literal">constant_type</code> +and <code class="literal">constant_ref_type</code> serve for this purpose. +They are used as: +</p> +<pre class="programlisting"> +var_type<T>::type delayed_i(var(i)); +constant_type<T>::type delayed_c(constant(c)); +</pre> +<p> +The first line defines the variable <code class="literal">delayed_i</code> which is a delayed version of the variable <code class="literal">i</code> of type <code class="literal">T</code>. +Analogously, the second line defines the constant <code class="literal">delayed_c</code> as a delayed version of the constant <code class="literal">c</code>. +For example: + +</p> +<pre class="programlisting"> +int i = 0; int j; +for_each(a.begin(), a.end(), (var(j) = _1, _1 = var(i), var(i) = var(j))); +</pre> +<p> +is equivalent to: +</p> +<pre class="programlisting"> +int i = 0; int j; +var_type<int>::type vi(var(i)), vj(var(j)); +for_each(a.begin(), a.end(), (vj = _1, _1 = vi, vi = vj)); +</pre> +<p> +Here is an example of naming a delayed constant: +</p> +<pre class="programlisting"> +constant_type<char>::type space(constant(' ')); +for_each(a.begin(),a.end(), cout << space << _1); +</pre> +</div> +<div class="simplesect" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="id1242898"></a>About assignment and subscript operators</h5></div></div></div> +<p> +As described in <a href="le_in_details.html#lambda.assignment_and_subscript" title="Assignment and subscript operators">the section called “Assignment and subscript operators”</a>, assignment and subscripting operators are always defined as member functions. +This means, that for expressions of the form +<code class="literal">x = y</code> or <code class="literal">x[y]</code> to be interpreted as lambda expressions, the left-hand operand <code class="literal">x</code> must be a lambda expression. +Consequently, it is sometimes necessary to use <code class="literal">var</code> for this purpose. +We repeat the example from <a href="le_in_details.html#lambda.assignment_and_subscript" title="Assignment and subscript operators">the section called “Assignment and subscript operators”</a>: + +</p> +<pre class="programlisting"> +int i; +i = _1; // error +var(i) = _1; // ok +</pre> +<p> + +Note that the compound assignment operators <code class="literal">+=</code>, <code class="literal">-=</code> etc. can be defined as non-member functions, and thus they are interpreted as lambda expressions even if only the right-hand operand is a lambda expression. +Nevertheless, it is perfectly ok to delay the left operand explicitly. +For example, <code class="literal">i += _1</code> is equivalent to <code class="literal">var(i) += _1</code>. +</p> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.lambda_expressions_for_control_structures"></a>Lambda expressions for control structures</h4></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="le_in_details.html#lambda.switch_statement">Switch statement</a></span></dt></dl></div> +<p> +BLL defines several functions to create lambda functors that represent control structures. +They all take lambda functors as parameters and return <code class="literal">void</code>. +To start with an example, the following code outputs all even elements of some container <code class="literal">a</code>: + +</p> +<pre class="programlisting"> +for_each(a.begin(), a.end(), + if_then(_1 % 2 == 0, cout << _1)); +</pre> +<p> +The BLL supports the following function templates for control structures: + +</p> +<pre class="programlisting"> +if_then(condition, then_part) +if_then_else(condition, then_part, else_part) +if_then_else_return(condition, then_part, else_part) +while_loop(condition, body) +while_loop(condition) // no body case +do_while_loop(condition, body) +do_while_loop(condition) // no body case +for_loop(init, condition, increment, body) +for_loop(init, condition, increment) // no body case +switch_statement(...) +</pre> +<p> + +The return types of all control construct lambda functor is +<code class="literal">void</code>, except for <code class="literal">if_then_else_return</code>, +which wraps a call to the conditional operator +</p> +<pre class="programlisting"> +condition ? then_part : else_part +</pre> +<p> +The return type rules for this operator are somewhat complex. +Basically, if the branches have the same type, this type is the return type. +If the type of the branches differ, one branch, say of type +<code class="literal">A</code>, must be convertible to the other branch, +say of type <code class="literal">B</code>. +In this situation, the result type is <code class="literal">B</code>. +Further, if the common type is an lvalue, the return type will be an lvalue +too. +</p> +<p> +Delayed variables tend to be commonplace in control structure lambda expressions. +For instance, here we use the <code class="literal">var</code> function to turn the arguments of <code class="literal">for_loop</code> into lambda expressions. +The effect of the code is to add 1 to each element of a two-dimensional array: + +</p> +<pre class="programlisting"> +int a[5][10]; int i; +for_each(a, a+5, + for_loop(var(i)=0, var(i)<10, ++var(i), + _1[var(i)] += 1)); +</pre> +<p> +The BLL supports an alternative syntax for control expressions, suggested +by Joel de Guzmann. +By overloading the <code class="literal">operator[]</code> we can +get a closer resemblance with the built-in control structures: + +</p> +<pre class="programlisting"> +if_(condition)[then_part] +if_(condition)[then_part].else_[else_part] +while_(condition)[body] +do_[body].while_(condition) +for_(init, condition, increment)[body] +</pre> +<p> + +For example, using this syntax the <code class="literal">if_then</code> example above +can be written as: +</p> +<pre class="programlisting"> +for_each(a.begin(), a.end(), + if_(_1 % 2 == 0)[ cout << _1 ]) +</pre> +<p> + +As more experience is gained, we may end up deprecating one or the other +of these syntaces. + +</p> +<div class="section" lang="en"><div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.switch_statement"></a>Switch statement</h5></div></div></div></div> +<p> +The lambda expressions for <code class="literal">switch</code> control structures are more complex since the number of cases may vary. +The general form of a switch lambda expression is: + +</p> +<pre class="programlisting"> +switch_statement(<em class="parameter"><code>condition</code></em>, + case_statement<<em class="parameter"><code>label</code></em>>(<em class="parameter"><code>lambda expression</code></em>), + case_statement<<em class="parameter"><code>label</code></em>>(<em class="parameter"><code>lambda expression</code></em>), + ... + default_statement(<em class="parameter"><code>lambda expression</code></em>) +) +</pre> +<p> + +The <code class="literal"><em class="parameter"><code>condition</code></em></code> argument must be a lambda expression that creates a lambda functor with an integral return type. +The different cases are created with the <code class="literal">case_statement</code> functions, and the optional default case with the <code class="literal">default_statement</code> function. +The case labels are given as explicitly specified template arguments to <code class="literal">case_statement</code> functions and +<code class="literal">break</code> statements are implicitly part of each case. +For example, <code class="literal">case_statement<1>(a)</code>, where <code class="literal">a</code> is some lambda functor, generates the code: + +</p> +<pre class="programlisting"> +case 1: + <em class="parameter"><code>evaluate lambda functor</code></em> a; + break; +</pre> +<p> +The <code class="literal">switch_statement</code> function is specialized for up to 9 case statements. + +</p> +<p> +As a concrete example, the following code iterates over some container <code class="literal">v</code> and ouptuts “<span class="quote">zero</span>” for each <code class="literal">0</code>, “<span class="quote">one</span>” for each <code class="literal">1</code>, and “<span class="quote">other: <em class="parameter"><code>n</code></em></span>” for any other value <em class="parameter"><code>n</code></em>. +Note that another lambda expression is sequenced after the <code class="literal">switch_statement</code> to output a line break after each element: + +</p> +<pre class="programlisting"> +std::for_each(v.begin(), v.end(), + ( + switch_statement( + _1, + case_statement<0>(std::cout << constant("zero")), + case_statement<1>(std::cout << constant("one")), + default_statement(cout << constant("other: ") << _1) + ), + cout << constant("\n") + ) +); +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.exceptions"></a>Exceptions</h4></div></div></div> +<p> +The BLL provides lambda functors that throw and catch exceptions. +Lambda functors for throwing exceptions are created with the unary function <code class="literal">throw_exception</code>. +The argument to this function is the exception to be thrown, or a lambda functor which creates the exception to be thrown. +A lambda functor for rethrowing exceptions is created with the nullary <code class="literal">rethrow</code> function. +</p> +<p> +Lambda expressions for handling exceptions are somewhat more complex. +The general form of a lambda expression for try catch blocks is as follows: + +</p> +<pre class="programlisting"> +try_catch( + <em class="parameter"><code>lambda expression</code></em>, + catch_exception<<em class="parameter"><code>type</code></em>>(<em class="parameter"><code>lambda expression</code></em>), + catch_exception<<em class="parameter"><code>type</code></em>>(<em class="parameter"><code>lambda expression</code></em>), + ... + catch_all(<em class="parameter"><code>lambda expression</code></em>) +) +</pre> +<p> + +The first lambda expression is the try block. +Each <code class="literal">catch_exception</code> defines a catch block where the +explicitly specified template argument defines the type of the exception +to catch. + +The lambda expression within the <code class="literal">catch_exception</code> defines +the actions to take if the exception is caught. + +Note that the resulting exception handlers catch the exceptions as +references, i.e., <code class="literal">catch_exception<T>(...)</code> +results in the catch block: + +</p> +<pre class="programlisting"> +catch(T& e) { ... } +</pre> +<p> + +The last catch block can alternatively be a call to +<code class="literal">catch_exception<<em class="parameter"><code>type</code></em>></code> +or to +<code class="literal">catch_all</code>, which is the lambda expression equivalent to +<code class="literal">catch(...)</code>. + +</p> +<p> + +The <a href="le_in_details.html#ex:exceptions" title="Example 6.1. Throwing and handling exceptions in lambda expressions.">Example 6.1, “Throwing and handling exceptions in lambda expressions.”</a> demonstrates the use of the BLL +exception handling tools. +The first handler catches exceptions of type <code class="literal">foo_exception</code>. +Note the use of <code class="literal">_1</code> placeholder in the body of the handler. +</p> +<p> +The second handler shows how to throw exceptions, and demonstrates the +use of the <span class="emphasis"><em>exception placeholder</em></span><code class="literal">_e</code>. + +It is a special placeholder, which refers to the caught exception object +within the handler body. + +Here we are handling an exception of type <code class="literal">std::exception</code>, +which carries a string explaining the cause of the exception. + +This explanation can be queried with the zero-argument member +function <code class="literal">what</code>. + +The expression +<code class="literal">bind(&std::exception::what, _e)</code> creates the lambda +function for making that call. + +Note that <code class="literal">_e</code> cannot be used outside of an exception handler lambda expression. + + +The last line of the second handler constructs a new exception object and +throws that with <code class="literal">throw exception</code>. + +Constructing and destructing objects within lambda expressions is +explained in <a href="le_in_details.html#lambda.construction_and_destruction" title="Construction and destruction">the section called “Construction and destruction”</a></p> +<p> +Finally, the third handler (<code class="literal">catch_all</code>) demonstrates +rethrowing exceptions. +</p> +<div class="example"> +<a name="ex:exceptions"></a><p class="title"><b>Example 6.1. Throwing and handling exceptions in lambda expressions.</b></p> +<pre class="programlisting"> +for_each( + a.begin(), a.end(), + try_catch( + bind(foo, _1), // foo may throw + catch_exception<foo_exception>( + cout << constant("Caught foo_exception: ") + << "foo was called with argument = " << _1 + ), + catch_exception<std::exception>( + cout << constant("Caught std::exception: ") + << bind(&std::exception::what, _e), + throw_exception(bind(constructor<bar_exception>(), _1))) + ), + catch_all( + (cout << constant("Unknown"), rethrow()) + ) + ) +); +</pre> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.construction_and_destruction"></a>Construction and destruction</h4></div></div></div> +<p> +Operators <code class="literal">new</code> and <code class="literal">delete</code> can be +overloaded, but their return types are fixed. + +Particularly, the return types cannot be lambda functors, +which prevents them to be overloaded for lambda expressions. + +It is not possible to take the address of a constructor, +hence constructors cannot be used as target functions in bind expressions. + +The same is true for destructors. + +As a way around these constraints, BLL defines wrapper classes for +<code class="literal">new</code> and <code class="literal">delete</code> calls, +as well as for constructors and destructors. + +Instances of these classes are function objects, that can be used as +target functions of bind expressions. + +For example: + +</p> +<pre class="programlisting"> +int* a[10]; +for_each(a, a+10, _1 = bind(new_ptr<int>())); +for_each(a, a+10, bind(delete_ptr(), _1)); +</pre> +<p> + +The <code class="literal">new_ptr<int>()</code> expression creates +a function object that calls <code class="literal">new int()</code> when invoked, +and wrapping that inside <code class="literal">bind</code> makes it a lambda functor. + +In the same way, the expression <code class="literal">delete_ptr()</code> creates +a function object that invokes <code class="literal">delete</code> on its argument. + +Note that <code class="literal">new_ptr<<em class="parameter"><code>T</code></em>>()</code> +can take arguments as well. + +They are passed directly to the constructor invocation and thus allow +calls to constructors which take arguments. + +</p> +<p> + +As an example of constructor calls in lambda expressions, +the following code reads integers from two containers <code class="literal">x</code> +and <code class="literal">y</code>, +constructs pairs out of them and inserts them into a third container: + +</p> +<pre class="programlisting"> +vector<pair<int, int> > v; +transform(x.begin(), x.end(), y.begin(), back_inserter(v), + bind(constructor<pair<int, int> >(), _1, _2)); +</pre> +<p><a href="le_in_details.html#table:constructor_destructor_fos" title="Table 6.1. Construction and destruction related function objects.">Table 6.1, “Construction and destruction related function objects.”</a> lists all the function +objects related to creating and destroying objects, + showing the expression to create and call the function object, +and the effect of evaluating that expression. + +</p> +<div class="table"> +<a name="table:constructor_destructor_fos"></a><p class="title"><b>Table 6.1. Construction and destruction related function objects.</b></p> +<table class="table" summary="Construction and destruction related function objects."> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th>Function object call</th> +<th>Wrapped expression</th> +</tr></thead> +<tbody> +<tr> +<td><code class="literal">constructor<T>()(<em class="parameter"><code>arg_list</code></em>)</code></td> +<td>T(<em class="parameter"><code>arg_list</code></em>)</td> +</tr> +<tr> +<td><code class="literal">destructor()(a)</code></td> +<td> +<code class="literal">a.~A()</code>, where <code class="literal">a</code> is of type <code class="literal">A</code> +</td> +</tr> +<tr> +<td><code class="literal">destructor()(pa)</code></td> +<td> +<code class="literal">pa->~A()</code>, where <code class="literal">pa</code> is of type <code class="literal">A*</code> +</td> +</tr> +<tr> +<td><code class="literal">new_ptr<T>()(<em class="parameter"><code>arg_list</code></em>)</code></td> +<td><code class="literal">new T(<em class="parameter"><code>arg_list</code></em>)</code></td> +</tr> +<tr> +<td><code class="literal">new_array<T>()(sz)</code></td> +<td><code class="literal">new T[sz]</code></td> +</tr> +<tr> +<td><code class="literal">delete_ptr()(p)</code></td> +<td><code class="literal">delete p</code></td> +</tr> +<tr> +<td><code class="literal">delete_array()(p)</code></td> +<td><code class="literal">delete p[]</code></td> +</tr> +</tbody> +</table> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1243846"></a>Special lambda expressions</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="le_in_details.html#id1243850">Preventing argument substitution</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#lambda.rvalues_as_actual_arguments">Rvalues as actual arguments to lambda functors</a></span></dt> +</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="id1243850"></a>Preventing argument substitution</h5></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="le_in_details.html#lambda.unlambda">Unlambda</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#id1244056">Protect</a></span></dt> +</dl></div> +<p> +When a lambda functor is called, the default behavior is to substitute +the actual arguments for the placeholders within all subexpressions. + +This section describes the tools to prevent the substitution and +evaluation of a subexpression, and explains when these tools should be used. +</p> +<p> +The arguments to a bind expression can be arbitrary lambda expressions, +e.g., other bind expressions. + +For example: + +</p> +<pre class="programlisting"> +int foo(int); int bar(int); +... +int i; +bind(foo, bind(bar, _1)(i); +</pre> +<p> + +The last line makes the call <code class="literal">foo(bar(i));</code> + +Note that the first argument in a bind expression, the target function, +is no exception, and can thus be a bind expression too. + +The innermost lambda functor just has to return something that can be used +as a target function: another lambda functor, function pointer, +pointer to member function etc. + +For example, in the following code the innermost lambda functor makes +a selection between two functions, and returns a pointer to one of them: + +</p> +<pre class="programlisting"> +int add(int a, int b) { return a+b; } +int mul(int a, int b) { return a*b; } + +int(*)(int, int) add_or_mul(bool x) { + return x ? add : mul; +} + +bool condition; int i; int j; +... +bind(bind(&add_or_mul, _1), _2, _3)(condition, i, j); +</pre> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h6 class="title"> +<a name="lambda.unlambda"></a>Unlambda</h6></div></div></div> +<p>A nested bind expression may occur inadvertently, +if the target function is a variable with a type that depends on a +template parameter. + +Typically the target function could be a formal parameter of a +function template. + +In such a case, the programmer may not know whether the target function is a lambda functor or not. +</p> +<p>Consider the following function template: + +</p> +<pre class="programlisting"> +template<class F> +int nested(const F& f) { + int x; + ... + bind(f, _1)(x); + ... +} +</pre> +<p> + +Somewhere inside the function the formal parameter +<code class="literal">f</code> is used as a target function in a bind expression. + +In order for this <code class="literal">bind</code> call to be valid, +<code class="literal">f</code> must be a unary function. + +Suppose the following two calls to <code class="literal">nested</code> are made: + +</p> +<pre class="programlisting"> +int foo(int); +int bar(int, int); +nested(&foo); +nested(bind(bar, 1, _1)); +</pre> +<p> + +Both are unary functions, or function objects, with appropriate argument +and return types, but the latter will not compile. + +In the latter call, the bind expression inside <code class="literal">nested</code> +will become: + +</p> +<pre class="programlisting"> +bind(bind(bar, 1, _1), _1) +</pre> +<p> + +When this is invoked with <code class="literal">x</code>, +after substituitions we end up trying to call + +</p> +<pre class="programlisting"> +bar(1, x)(x) +</pre> +<p> + +which is an error. + +The call to <code class="literal">bar</code> returns int, +not a unary function or function object. +</p> +<p> +In the example above, the intent of the bind expression in the +<code class="literal">nested</code> function is to treat <code class="literal">f</code> +as an ordinary function object, instead of a lambda functor. + +The BLL provides the function template <code class="literal">unlambda</code> to +express this: a lambda functor wrapped inside <code class="literal">unlambda</code> +is not a lambda functor anymore, and does not take part into the +argument substitution process. + +Note that for all other argument types <code class="literal">unlambda</code> is +an identity operation, except for making non-const objects const. +</p> +<p> +Using <code class="literal">unlambda</code>, the <code class="literal">nested</code> +function is written as: + +</p> +<pre class="programlisting"> +template<class F> +int nested(const F& f) { + int x; + ... + bind(unlambda(f), _1)(x); + ... +} +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h6 class="title"> +<a name="id1244056"></a>Protect</h6></div></div></div> +<p> +The <code class="literal">protect</code> function is related to unlambda. + +It is also used to prevent the argument substitution taking place, +but whereas <code class="literal">unlambda</code> turns a lambda functor into +an ordinary function object for good, <code class="literal">protect</code> does +this temporarily, for just one evaluation round. + +For example: + +</p> +<pre class="programlisting"> +int x = 1, y = 10; +(_1 + protect(_1 + 2))(x)(y); +</pre> +<p> + +The first call substitutes <code class="literal">x</code> for the leftmost +<code class="literal">_1</code>, and results in another lambda functor +<code class="literal">x + (_1 + 2)</code>, which after the call with +<code class="literal">y</code> becomes <code class="literal">x + (y + 2)</code>, +and thus finally 13. +</p> +<p> +Primary motivation for including <code class="literal">protect</code> into the library, +was to allow nested STL algorithm invocations +(<a href="le_in_details.html#lambda.nested_stl_algorithms" title="Nesting STL algorithm invocations">the section called “Nesting STL algorithm invocations”</a>). +</p> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.rvalues_as_actual_arguments"></a>Rvalues as actual arguments to lambda functors</h5></div></div></div> +<p> +Actual arguments to the lambda functors cannot be non-const rvalues. +This is due to a deliberate design decision: either we have this restriction, +or there can be no side-effects to the actual arguments. + +There are ways around this limitation. + +We repeat the example from section +<a href="using_library.html#lambda.actual_arguments_to_lambda_functors" title="About actual arguments to lambda functors">the section called “About actual arguments to lambda functors”</a> and list the +different solutions: + +</p> +<pre class="programlisting"> +int i = 1; int j = 2; +(_1 + _2)(i, j); // ok +(_1 + _2)(1, 2); // error (!) +</pre> +<div class="orderedlist"><ol type="1"> +<li><p> +If the rvalue is of a class type, the return type of the function that +creates the rvalue should be defined as const. +Due to an unfortunate language restriction this does not work for +built-in types, as built-in rvalues cannot be const qualified. +</p></li> +<li> +<p> +If the lambda function call is accessible, the <code class="literal">make_const</code> +function can be used to <span class="emphasis"><em>constify</em></span> the rvalue. E.g.: + +</p> +<pre class="programlisting"> +(_1 + _2)(make_const(1), make_const(2)); // ok +</pre> +<p> + +Commonly the lambda function call site is inside a standard algorithm +function template, preventing this solution to be used. + +</p> +</li> +<li> +<p> +If neither of the above is possible, the lambda expression can be wrapped +in a <code class="literal">const_parameters</code> function. +It creates another type of lambda functor, which takes its arguments as +const references. For example: + +</p> +<pre class="programlisting"> +const_parameters(_1 + _2)(1, 2); // ok +</pre> +<p> + +Note that <code class="literal">const_parameters</code> makes all arguments const. +Hence, in the case were one of the arguments is a non-const rvalue, +and another argument needs to be passed as a non-const reference, +this approach cannot be used. +</p> +</li> +<li> +<p>If none of the above is possible, there is still one solution, +which unfortunately can break const correctness. + +The solution is yet another lambda functor wrapper, which we have named +<code class="literal">break_const</code> to alert the user of the potential dangers +of this function. + +The <code class="literal">break_const</code> function creates a lambda functor that +takes its arguments as const, and casts away constness prior to the call +to the original wrapped lambda functor. + +For example: +</p> +<pre class="programlisting"> +int i; +... +(_1 += _2)(i, 2); // error, 2 is a non-const rvalue +const_parameters(_1 += _2)(i, 2); // error, i becomes const +break_const(_1 += _2)(i, 2); // ok, but dangerous +</pre> +<p> + +Note, that the results of <code class="literal"> break_const</code> or +<code class="literal">const_parameters</code> are not lambda functors, +so they cannot be used as subexpressions of lambda expressions. For instance: + +</p> +<pre class="programlisting"> +break_const(_1 + _2) + _3; // fails. +const_parameters(_1 + _2) + _3; // fails. +</pre> +<p> + +However, this kind of code should never be necessary, +since calls to sub lambda functors are made inside the BLL, +and are not affected by the non-const rvalue problem. +</p> +</li> +</ol></div> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1244283"></a>Casts, sizeof and typeid</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="le_in_details.html#lambda.cast_expressions"> +Cast expressions +</a></span></dt> +<dt><span class="section"><a href="le_in_details.html#id1244354">Sizeof and typeid</a></span></dt> +</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.cast_expressions"></a> +Cast expressions +</h5></div></div></div> +<p> +The BLL defines its counterparts for the four cast expressions +<code class="literal">static_cast</code>, <code class="literal">dynamic_cast</code>, +<code class="literal">const_cast</code> and <code class="literal">reinterpret_cast</code>. + +The BLL versions of the cast expressions have the prefix +<code class="literal">ll_</code>. + +The type to cast to is given as an explicitly specified template argument, +and the sole argument is the expression from which to perform the cast. + +If the argument is a lambda functor, the lambda functor is evaluated first. + +For example, the following code uses <code class="literal">ll_dynamic_cast</code> +to count the number of <code class="literal">derived</code> instances in the container +<code class="literal">a</code>: + +</p> +<pre class="programlisting"> +class base {}; +class derived : public base {}; + +vector<base*> a; +... +int count = 0; +for_each(a.begin(), a.end(), + if_then(ll_dynamic_cast<derived*>(_1), ++var(count))); +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="id1244354"></a>Sizeof and typeid</h5></div></div></div> +<p> +The BLL counterparts for these expressions are named +<code class="literal">ll_sizeof</code> and <code class="literal">ll_typeid</code>. + +Both take one argument, which can be a lambda expression. +The lambda functor created wraps the <code class="literal">sizeof</code> or +<code class="literal">typeid</code> call, and when the lambda functor is called +the wrapped operation is performed. + +For example: + +</p> +<pre class="programlisting"> +vector<base*> a; +... +for_each(a.begin(), a.end(), + cout << bind(&type_info::name, ll_typeid(*_1))); +</pre> +<p> + +Here <code class="literal">ll_typeid</code> creates a lambda functor for +calling <code class="literal">typeid</code> for each element. + +The result of a <code class="literal">typeid</code> call is an instance of +the <code class="literal">type_info</code> class, and the bind expression creates +a lambda functor for calling the <code class="literal">name</code> member +function of that class. + +</p> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.nested_stl_algorithms"></a>Nesting STL algorithm invocations</h4></div></div></div> +<p> +The BLL defines common STL algorithms as function object classes, +instances of which can be used as target functions in bind expressions. +For example, the following code iterates over the elements of a +two-dimensional array, and computes their sum. + +</p> +<pre class="programlisting"> +int a[100][200]; +int sum = 0; + +std::for_each(a, a + 100, + bind(ll::for_each(), _1, _1 + 200, protect(sum += _1))); +</pre> +<p> + +The BLL versions of the STL algorithms are classes, which define the function call operator (or several overloaded ones) to call the corresponding function templates in the <code class="literal">std</code> namespace. +All these structs are placed in the subnamespace <code class="literal">boost::lambda:ll</code>. +</p> +<p> +Note that there is no easy way to express an overloaded member function +call in a lambda expression. + +This limits the usefulness of nested STL algorithms, as for instance +the <code class="literal">begin</code> function has more than one overloaded +definitions in container templates. + +In general, something analogous to the pseudo-code below cannot be written: + +</p> +<pre class="programlisting"> +std::for_each(a.begin(), a.end(), + bind(ll::for_each(), _1.begin(), _1.end(), protect(sum += _1))); +</pre> +<p> + +Some aid for common special cases can be provided though. + +The BLL defines two helper function object classes, +<code class="literal">call_begin</code> and <code class="literal">call_end</code>, +which wrap a call to the <code class="literal">begin</code> and, respectively, +<code class="literal">end</code> functions of a container, and return the +<code class="literal">const_iterator</code> type of the container. + +With these helper templates, the above code becomes: +</p> +<pre class="programlisting"> +std::for_each(a.begin(), a.end(), + bind(ll::for_each(), + bind(call_begin(), _1), bind(call_end(), _1), + protect(sum += _1))); +</pre> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="using_library.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="extending.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/lambda/s03.html b/doc/html/lambda/s03.html new file mode 100644 index 0000000000..a49fd92da2 --- /dev/null +++ b/doc/html/lambda/s03.html @@ -0,0 +1,264 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Introduction</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="getting_started.html" title="Getting Started"> +<link rel="next" href="using_library.html" title="Using the library"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="getting_started.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="using_library.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="id1222695"></a>Introduction</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="s03.html#id1222698">Motivation</a></span></dt> +<dt><span class="section"><a href="s03.html#id1222933">Introduction to lambda expressions</a></span></dt> +</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1222698"></a>Motivation</h4></div></div></div> +<p>The Standard Template Library (STL) + [<a href="../lambda.html#cit:stepanov:94" title="[STL94]"><span class="abbrev">STL94</span></a>], now part of the C++ Standard Library [<a href="../lambda.html#cit:c++:98" title="[C++98]"><span class="abbrev">C++98</span></a>], is a generic container and algorithm library. +Typically STL algorithms operate on container elements via <span class="emphasis"><em>function objects</em></span>. These function objects are passed as arguments to the algorithms. +</p> +<p> +Any C++ construct that can be called with the function call syntax +is a function object. +The STL contains predefined function objects for some common cases (such as <code class="literal">plus</code>, <code class="literal">less</code> and <code class="literal">not1</code>). +As an example, one possible implementation for the standard <code class="literal">plus</code> template is: + +</p> +<pre class="programlisting"> +template <class T> : public binary_function<T, T, T> +struct plus { + T operator()(const T& i, const T& j) const { + return i + j; + } +}; +</pre> +<p> + +The base class <code class="literal">binary_function<T, T, T></code> contains typedefs for the argument and return types of the function object, which are needed to make the function object <span class="emphasis"><em>adaptable</em></span>. +</p> +<p> +In addition to the basic function object classes, such as the one above, +the STL contains <span class="emphasis"><em>binder</em></span> templates for creating a unary function object from an adaptable binary function object by fixing one of the arguments to a constant value. +For example, instead of having to explicitly write a function object class like: + +</p> +<pre class="programlisting"> +class plus_1 { + int _i; +public: + plus_1(const int& i) : _i(i) {} + int operator()(const int& j) { return _i + j; } +}; +</pre> +<p> + +the equivalent functionality can be achieved with the <code class="literal">plus</code> template and one of the binder templates (<code class="literal">bind1st</code>). +E.g., the following two expressions create function objects with identical functionalities; +when invoked, both return the result of adding <code class="literal">1</code> to the argument of the function object: + +</p> +<pre class="programlisting"> +plus_1(1) +bind1st(plus<int>(), 1) +</pre> +<p> + +The subexpression <code class="literal">plus<int>()</code> in the latter line is a binary function object which computes the sum of two integers, and <code class="literal">bind1st</code> invokes this function object partially binding the first argument to <code class="literal">1</code>. +As an example of using the above function object, the following code adds <code class="literal">1</code> to each element of some container <code class="literal">a</code> and outputs the results into the standard output stream <code class="literal">cout</code>. + +</p> +<pre class="programlisting"> +transform(a.begin(), a.end(), ostream_iterator<int>(cout), + bind1st(plus<int>(), 1)); +</pre> +<p> +To make the binder templates more generally applicable, the STL contains <span class="emphasis"><em>adaptors</em></span> for making +pointers or references to functions, and pointers to member functions, +adaptable. + +Finally, some STL implementations contain function composition operations as +extensions to the standard [<a href="../lambda.html#cit:sgi:02" title="[SGI02]"><span class="abbrev">SGI02</span></a>]. + </p> +<p> +All these tools aim at one goal: to make it possible to specify +<span class="emphasis"><em>unnamed functions</em></span> in a call of an STL algorithm, +in other words, to pass code fragments as an argument to a function. + +However, this goal is attained only partially. +The simple example above shows that the definition of unnamed functions +with the standard tools is cumbersome. + +Complex expressions involving functors, adaptors, binders and +function composition operations tend to be difficult to comprehend. + +In addition to this, there are significant restrictions in applying +the standard tools. E.g. the standard binders allow only one argument +of a binary function to be bound; there are no binders for +3-ary, 4-ary etc. functions. +</p> +<p> +The Boost Lambda Library provides solutions for the problems described above: + +</p> +<div class="itemizedlist"><ul type="disc"> +<li> +<p> +Unnamed functions can be created easily with an intuitive syntax. + +The above example can be written as: + +</p> +<pre class="programlisting"> +transform(a.begin(), a.end(), ostream_iterator<int>(cout), + 1 + _1); +</pre> +<p> + +or even more intuitively: + +</p> +<pre class="programlisting"> +for_each(a.begin(), a.end(), cout << (1 + _1)); +</pre> +</li> +<li><p> +Most of the restrictions in argument binding are removed, +arbitrary arguments of practically any C++ function can be bound. +</p></li> +<li><p> +Separate function composition operations are not needed, +as function composition is supported implicitly. + +</p></li> +</ul></div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1222933"></a>Introduction to lambda expressions</h4></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="s03.html#lambda.partial_function_application">Partial function application</a></span></dt> +<dt><span class="section"><a href="s03.html#lambda.terminology">Terminology</a></span></dt> +</dl></div> +<p> + Lambda expression are common in functional programming languages. + Their syntax varies between languages (and between different forms of lambda calculus), but the basic form of a lambda expressions is: + + +</p> +<pre class="programlisting"> +lambda x<sub>1</sub> ... x<sub>n</sub>.e +</pre> +<p> + + A lambda expression defines an unnamed function and consists of: + </p> +<div class="itemizedlist"><ul type="disc"> +<li><p> + the parameters of this function: <code class="literal">x<sub>1</sub> ... x<sub>n</sub></code>. + </p></li> +<li><p>the expression e which computes the value of the function in terms of the parameters <code class="literal">x<sub>1</sub> ... x<sub>n</sub></code>. + </p></li> +</ul></div> +<p> + + A simple example of a lambda expression is +</p> +<pre class="programlisting"> +lambda x y.x+y +</pre> +<p> +Applying the lambda function means substituting the formal parameters with the actual arguments: +</p> +<pre class="programlisting"> +(lambda x y.x+y) 2 3 = 2 + 3 = 5 +</pre> +<p> +In the C++ version of lambda expressions the <code class="literal">lambda x<sub>1</sub> ... x<sub>n</sub></code> part is missing and the formal parameters have predefined names. +In the current version of the library, +there are three such predefined formal parameters, +called <span class="emphasis"><em>placeholders</em></span>: +<code class="literal">_1</code>, <code class="literal">_2</code> and <code class="literal">_3</code>. +They refer to the first, second and third argument of the function defined +by the lambda expression. + +For example, the C++ version of the definition +</p> +<pre class="programlisting">lambda x y.x+y</pre> +<p> +is +</p> +<pre class="programlisting">_1 + _2</pre> +<p> +Hence, there is no syntactic keyword for C++ lambda expressions. + The use of a placeholder as an operand implies that the operator invocation is a lambda expression. + However, this is true only for operator invocations. + Lambda expressions containing function calls, control structures, casts etc. require special syntactic constructs. + Most importantly, function calls need to be wrapped inside a <code class="literal">bind</code> function. + + As an example, consider the lambda expression: + + </p> +<pre class="programlisting">lambda x y.foo(x,y)</pre> +<p> + + Rather than <code class="literal">foo(_1, _2)</code>, the C++ counterpart for this expression is: + + </p> +<pre class="programlisting">bind(foo, _1, _2)</pre> +<p> + + We refer to this type of C++ lambda expressions as <span class="emphasis"><em>bind expressions</em></span>. + </p> +<p>A lambda expression defines a C++ function object, hence function application syntax is like calling any other function object, for instance: <code class="literal">(_1 + _2)(i, j)</code>. + + + </p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.partial_function_application"></a>Partial function application</h5></div></div></div> +<p> +A bind expression is in effect a <span class="emphasis"><em>partial function application</em></span>. +In partial function application, some of the arguments of a function are bound to fixed values. + The result is another function, with possibly fewer arguments. + When called with the unbound arguments, this new function invokes the original function with the merged argument list of bound and unbound arguments. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="lambda.terminology"></a>Terminology</h5></div></div></div> +<p> + A lambda expression defines a function. A C++ lambda expression concretely constructs a function object, <span class="emphasis"><em>a functor</em></span>, when evaluated. We use the name <span class="emphasis"><em>lambda functor</em></span> to refer to such a function object. + Hence, in the terminology adopted here, the result of evaluating a lambda expression is a lambda functor. + </p> +</div> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="getting_started.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="using_library.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/lambda/s07.html b/doc/html/lambda/s07.html new file mode 100644 index 0000000000..fab368fe84 --- /dev/null +++ b/doc/html/lambda/s07.html @@ -0,0 +1,314 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Practical considerations</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="extending.html" title="Extending return type deduction system"> +<link rel="next" href="s08.html" title="Relation to other Boost libraries"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="extending.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s08.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="id1245398"></a>Practical considerations</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="s07.html#id1245402">Performance</a></span></dt> +<dt><span class="section"><a href="s07.html#id1245714">About compiling</a></span></dt> +<dt><span class="section"><a href="s07.html#id1245749">Portability</a></span></dt> +</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1245402"></a>Performance</h4></div></div></div> +<p>In theory, all overhead of using STL algorithms and lambda functors +compared to hand written loops can be optimized away, just as the overhead +from standard STL function objects and binders can. + +Depending on the compiler, this can also be true in practice. +We ran two tests with the GCC 3.0.4 compiler on 1.5 GHz Intel Pentium 4. +The optimization flag -03 was used. +</p> +<p> +In the first test we compared lambda functors against explicitly written +function objects. +We used both of these styles to define unary functions which multiply the +argument repeatedly by itself. +We started with the identity function, going up to +x<sup>5</sup>. +The expressions were called inside a <code class="literal">std::transform</code> loop, +reading the argument from one <code class="literal">std::vector<int></code> +and placing the result into another. +The length of the vectors was 100 elements. +The running times are listed in +<a href="s07.html#table:increasing_arithmetic_test" title="Table 6.3. Test 1">Table 6.3, “Test 1”</a>. + +We can observe that there is no significant difference between the +two approaches. +</p> +<p> +In the second test we again used <code class="literal">std::transform</code> to +perform an operation to each element in a 100-element long vector. +This time the element type of the vectors was <code class="literal">double</code> +and we started with very simple arithmetic expressions and moved to +more complex ones. +The running times are listed in <a href="s07.html#table:ll_vs_stl_test" title="Table 6.4. Test 2">Table 6.4, “Test 2”</a>. + +Here, we also included classic STL style unnamed functions into tests. +We do not show these expressions, as they get rather complex. +For example, the +last expression in <a href="s07.html#table:ll_vs_stl_test" title="Table 6.4. Test 2">Table 6.4, “Test 2”</a> written with +classic STL tools contains 7 calls to <code class="literal">compose2</code>, +8 calls to <code class="literal">bind1st</code> +and altogether 14 constructor invocations for creating +<code class="literal">multiplies</code>, <code class="literal">minus</code> +and <code class="literal">plus</code> objects. + +In this test the BLL expressions are a little slower (roughly 10% on average, +less than 14% in all cases) +than the corresponding hand-written function objects. +The performance hit is a bit greater with classic STL expressions, +up to 27% for the simplest expressios. +</p> +<p> +The tests suggest that the BLL does not introduce a loss of performance +compared to STL function objects. +With a reasonable optimizing compiler, one should expect the performance characteristics be comparable to using classic STL. +Moreover, with simple expressions the performance can be expected to be close +to that of explicitly written function objects. + + + +Note however, that evaluating a lambda functor consist of a sequence of calls to small functions that are declared inline. +If the compiler fails to actually expand these functions inline, +the performance can suffer. +The running time can more than double if this happens. +Although the above tests do not include such an expression, we have experienced +this for some seemingly simple expressions. + + +</p> +<div class="table"> +<a name="table:increasing_arithmetic_test"></a><p class="title"><b>Table 6.3. Test 1</b></p> +<div class="caption">CPU time of expressions with integer multiplication written as a lambda expression and as a traditional hand-coded function object class. +The running times are expressed in arbitrary units.</div> +<table class="table" summary="Test 1"> +<colgroup> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th>expression</th> +<th>lambda expression</th> +<th>hand-coded function object</th> +</tr></thead> +<tbody> +<tr> +<td>x</td> +<td>240</td> +<td>230</td> +</tr> +<tr> +<td>x*x</td> +<td>340</td> +<td>350</td> +</tr> +<tr> +<td>x*x*x</td> +<td>770</td> +<td>760</td> +</tr> +<tr> +<td>x*x*x*x</td> +<td>1180</td> +<td>1210</td> +</tr> +<tr> +<td>x*x*x*x*x</td> +<td>1950</td> +<td>1910</td> +</tr> +</tbody> +</table> +</div> +<div class="table"> +<a name="table:ll_vs_stl_test"></a><p class="title"><b>Table 6.4. Test 2</b></p> +<div class="caption">CPU time of arithmetic expressions written as lambda +expressions, as classic STL unnamed functions (using <code class="literal">compose2</code>, <code class="literal">bind1st</code> etc.) and as traditional hand-coded function object classes. +Using BLL terminology, +<code class="literal">a</code> and <code class="literal">b</code> are bound arguments in the expressions, and <code class="literal">x</code> is open. +All variables were of types <code class="literal">double</code>. +The running times are expressed in arbitrary units.</div> +<table class="table" summary="Test 2"> +<colgroup> +<col> +<col> +<col> +<col> +</colgroup> +<thead><tr> +<th>expression</th> +<th>lambda expression</th> +<th>classic STL expression</th> +<th>hand-coded function object</th> +</tr></thead> +<tbody> +<tr> +<td>ax</td> +<td>330</td> +<td>370</td> +<td>290</td> +</tr> +<tr> +<td>-ax</td> +<td>350</td> +<td>370</td> +<td>310</td> +</tr> +<tr> +<td>ax-(a+x)</td> +<td>470</td> +<td>500</td> +<td>420</td> +</tr> +<tr> +<td>(ax-(a+x))(a+x)</td> +<td>620</td> +<td>670</td> +<td>600</td> +</tr> +<tr> +<td>((ax) - (a+x))(bx - (b+x))(ax - (b+x))(bx - (a+x))</td> +<td>1660</td> +<td>1660</td> +<td>1460</td> +</tr> +</tbody> +</table> +</div> +<p>Some additional performance testing with an earlier version of the +library is described +[<a href="../lambda.html#cit:jarvi:00" title="[Jär00]"><span class="abbrev">Jär00</span></a>]. +</p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1245714"></a>About compiling</h4></div></div></div> +<p>The BLL uses templates rather heavily, performing numerous recursive instantiations of the same templates. +This has (at least) three implications: +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p> +While it is possible to write incredibly complex lambda expressions, it probably isn't a good idea. +Compiling such expressions may end up requiring a lot of memory +at compile time, and being slow to compile. +</p></li> +<li><p> +The types of lambda functors that result from even the simplest lambda expressions are cryptic. +Usually the programmer doesn't need to deal with the lambda functor types at all, but in the case of an error in a lambda expression, the compiler usually outputs the types of the lambda functors involved. +This can make the error messages very long and difficult to interpret, particularly if the compiler outputs the whole chain of template instantiations. +</p></li> +<li><p> +The C++ Standard suggests a template nesting level of 17 to help detect infinite recursion. +Complex lambda templates can easily exceed this limit. +Most compilers allow a greater number of nested templates, but commonly require the limit explicitly increased with a command line argument. +</p></li> +</ul></div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1245749"></a>Portability</h4></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="s07.html#id1245773">Test coverage</a></span></dt></dl></div> +<p> +The BLL works with the following compilers, that is, the compilers are capable of compiling the test cases that are included with the BLL: + + </p> +<div class="itemizedlist"><ul type="disc"> +<li>GCC 3.0.4 + </li> +<li>KCC 4.0f with EDG 2.43.1 + </li> +<li>GCC 2.96 (fails with one test case, the <code class="filename">exception_test.cpp</code> results in an internal compiler error. +) + + </li> +</ul></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="id1245773"></a>Test coverage</h5></div></div></div> +<p>The following list describes the test files included and the features that each file covers: + +</p> +<div class="itemizedlist"><ul type="disc"> +<li><p><code class="filename">bind_tests_simple.cpp</code> : Bind expressions of different arities and types of target functions: function pointers, function objects and member functions. +Function composition with bind expressions.</p></li> +<li><p><code class="filename">bind_tests_simple_function_references.cpp</code> : +Repeats all tests from <code class="filename">bind_tests_simple.cpp</code> where the target function is a function pointer, but uses function references instead. +</p></li> +<li><p><code class="filename">bind_tests_advanced.cpp</code> : Contains tests for nested bind expressions, <code class="literal">unlambda</code>, <code class="literal">protect</code>, <code class="literal">const_parameters</code> and <code class="literal">break_const</code>. +Tests passing lambda functors as actual arguments to other lambda functors, currying, and using the <code class="literal">sig</code> template to specify the return type of a function object. +</p></li> +<li><p><code class="filename">operator_tests_simple.cpp</code> : +Tests using all operators that are overloaded for lambda expressions, that is, unary and binary arithmetic, +bitwise, +comparison, +logical, +increment and decrement, +compound, +assignment, +subscrict, +address of, +dereference, and comma operators. +The streaming nature of shift operators is tested, as well as pointer arithmetic with plus and minus operators. +</p></li> +<li><p><code class="filename">member_pointer_test.cpp</code> : The pointer to member operator is complex enough to warrant a separate test file. +</p></li> +<li><p><code class="filename">control_structures.cpp</code> : +Tests for the looping and if constructs. +</p></li> +<li><p><code class="filename">switch_construct.cpp</code> : +Includes tests for all supported arities of the switch statement, both with and without the default case. +</p></li> +<li><p><code class="filename">exception_test.cpp</code> : +Includes tests for throwing exceptions and for try/catch constructs with varying number of catch blocks. +</p></li> +<li><p><code class="filename">constructor_tests.cpp</code> : +Contains tests for <code class="literal">constructor</code>, <code class="literal">destructor</code>, <code class="literal">new_ptr</code>, <code class="literal">delete_ptr</code>, <code class="literal">new_array</code> and <code class="literal">delete_array</code>. +</p></li> +<li><p><code class="filename">cast_test.cpp</code> : Tests for the four cast expressions, as well as <code class="filename">typeid</code> and <code class="literal">sizeof</code>. +</p></li> +<li><p><code class="filename">extending_return_type_traits.cpp</code> : Tests extending the return type deduction system for user defined types. +Contains several user defined operators and the corresponding specializations for the return type deduction templates. +</p></li> +<li><p><code class="filename">is_instance_of_test.cpp</code> : Includes tests for an internally used traits template, which can detect whether a given type is an instance of a certain template or not. +</p></li> +<li><p><code class="filename">bll_and_function.cpp</code> : +Contains tests for using <code class="literal">boost::function</code> together with lambda functors. +</p></li> +</ul></div> +</div> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="extending.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s08.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/lambda/s08.html b/doc/html/lambda/s08.html new file mode 100644 index 0000000000..dc32982cc5 --- /dev/null +++ b/doc/html/lambda/s08.html @@ -0,0 +1,177 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Relation to other Boost libraries</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="s07.html" title="Practical considerations"> +<link rel="next" href="s09.html" title="Contributors"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="s07.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s09.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="id1246000"></a>Relation to other Boost libraries</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="s08.html#id1246004">Boost Function</a></span></dt> +<dt><span class="section"><a href="s08.html#id1246081">Boost Bind</a></span></dt> +</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1246004"></a>Boost Function</h4></div></div></div> +<p>Sometimes it is convenient to store lambda functors in variables. +However, the types of even the simplest lambda functors are long and unwieldy, and it is in general unfeasible to declare variables with lambda functor types. +<span class="emphasis"><em>The Boost Function library</em></span>[<a href="../lambda.html#cit:boost::function" title="[function]"><span class="abbrev">function</span></a>] defines wrappers for arbitrary function objects, for example +lambda functors; and these wrappers have types that are easy to type out. + +For example: + +</p> +<pre class="programlisting"> +boost::function<int(int, int)> f = _1 + _2; +boost::function<int&(int&)> g = (_1 += 10); +int i = 1, j = 2; +f(i, j); // returns 3 +g(i); // sets i to = 11; +</pre> +<p> + +The return and parameter types of the wrapped function object must be written explicilty as the template argument to the wrapper template <code class="literal">boost::function</code>; even when lambda functors, which otherwise have generic parameters, are wrapped. +Wrapping a function object with <code class="literal">boost::function</code> introduces a performance cost comparable to virtual function dispatch, though virtual functions are not actually used. + +Note that storing lambda functors inside <code class="literal">boost::function</code> +introduces a danger. +Certain types of lambda functors may store references to the bound +arguments, instead as taking copies of the arguments of the lambda expression. +When temporary lambda functor objects are used +in STL algorithm invocations this is always safe, as the lambda functor gets +destructed immediately after the STL algortihm invocation is completed. + +However, a lambda functor wrapped inside <code class="literal">boost::function</code> +may continue to exist longer, creating the possibility of dangling references. +For example: + +</p> +<pre class="programlisting"> +int* sum = new int(); +*sum = 0; +boost::function<int&(int)> counter = *sum += _1; +counter(5); // ok, *sum = 5; +delete sum; +counter(3); // error, *sum does not exist anymore +</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="id1246081"></a>Boost Bind</h4></div></div></div> +<div class="toc"><dl><dt><span class="section"><a href="s08.html#id1246134">First argument of bind expression</a></span></dt></dl></div> +<p><span class="emphasis"><em>The Boost Bind</em></span>[<a href="../lambda.html#cit:boost::bind" title="[bind]"><span class="abbrev">bind</span></a>] library has partially overlapping functionality with the BLL. +Basically, the Boost Bind library (BB in the sequel) implements the bind expression part of BLL. +There are, however, some semantical differerences. +</p> +<p> +The BLL and BB evolved separately, and have different implementations. +This means that the bind expressions from the BB cannot be used within +bind expressions, or within other type of lambda expressions, of the BLL. +The same holds for using BLL bind expressions in the BB. +The libraries can coexist, however, as +the names of the BB library are in <code class="literal">boost</code> namespace, +whereas the BLL names are in <code class="literal">boost::lambda</code> namespace. +</p> +<p> +The BLL requires a compiler that is reasonably conformant to the +C++ standard, whereas the BB library is more portable, and works with +a larger set of compilers. +</p> +<p> +The following two sections describe what are the semantic differences +between the bind expressions in BB and BLL. +</p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h5 class="title"> +<a name="id1246134"></a>First argument of bind expression</h5></div></div></div> + +In BB the first argument of the bind expression, the target function, +is treated differently from the other arguments, +as no argument substitution takes place within that argument. +In BLL the first argument is not a special case in this respect. + +For example: + +<pre class="programlisting"> +template<class F> +int foo(const F& f) { + int x; + .. + bind(f, _1)(x); + ... +} +</pre> +<pre class="programlisting"> +int bar(int, int); +nested(bind(bar, 1, _1)); +</pre> + +The bind expression inside <code class="literal">foo</code> becomes: +<pre class="programlisting"> +bind(bind(bar, 1, _1), _1)(x) +</pre> + +The BLL interpretes this as: +<pre class="programlisting"> +bar(1, x)(x) +</pre> +whereas the BB library as +<pre class="programlisting"> +bar(1, x) +</pre> + +To get this functionality in BLL, the bind expression inside the <code class="literal">foo</code> function can be written as: +<pre class="programlisting"> +bind(unlambda(f), _1)(x); +</pre> +as explained in <a href="le_in_details.html#lambda.unlambda" title="Unlambda">the section called “Unlambda”</a>. + +</div> +<p> +The BB library supports up to nine placeholders, while the BLL +defines only three placeholders. +The rationale for not providing more, is that the highest arity of the +function objects accepted by any STL algorithm is two. +The placeholder count is easy to increase in the BB library. +In BLL it is possible, but more laborous. +The BLL currently passes the actual arguments to the lambda functors +internally just as they are and does not wrap them inside a tuple object. +The reason for this is that some widely used compilers are not capable +of optimizing the intermediate tuple objects away. +The creation of the intermediate tuples would cause a significant +performance hit, particularly for the simplest (and thus the most common) +lambda functors. +We are working on a hybrid approach, which will allow more placeholders +but not compromise the performance of simple lambda functors. +</p> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="s07.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="s09.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/lambda/s09.html b/doc/html/lambda/s09.html new file mode 100644 index 0000000000..ac7745e338 --- /dev/null +++ b/doc/html/lambda/s09.html @@ -0,0 +1,45 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Contributors</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="s08.html" title="Relation to other Boost libraries"> +<link rel="next" href="../apa.html" title="Appendix A. Rationale for some of the design decisions"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="s08.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="../apa.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="id1246205"></a>Contributors</h3></div></div></div> + +The main body of the library was written by Jaakko Järvi and Gary Powell. +We've got outside help, suggestions and ideas from Jeremy Siek, Peter Higley, Peter Dimov, Valentin Bonnard, William Kempf. +We would particularly like to mention Joel de Guzmann and his work with +Phoenix which has influenced BLL significantly, making it considerably simpler +to extend the library with new features. + +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="s08.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="../apa.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> diff --git a/doc/html/lambda/using_library.html b/doc/html/lambda/using_library.html new file mode 100644 index 0000000000..4e8e98dda9 --- /dev/null +++ b/doc/html/lambda/using_library.html @@ -0,0 +1,310 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Using the library</title> +<link rel="stylesheet" href="../boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1"> +<link rel="start" href="../index.html" title="The Boost C++ Libraries"> +<link rel="up" href="../lambda.html" title="Chapter 6. Boost.Lambda"> +<link rel="prev" href="s03.html" title="Introduction"> +<link rel="next" href="le_in_details.html" title="Lambda expressions in details"> +</head> +<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> +<table cellpadding="2" width="100%"> +<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../../boost.png"></td> +<td align="center"><a href="../../../index.htm">Home</a></td> +<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> +<td align="center"><a href="../../../people/people.htm">People</a></td> +<td align="center"><a href="../../../more/faq.htm">FAQ</a></td> +<td align="center"><a href="../../../more/index.htm">More</a></td> +</table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="s03.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="le_in_details.html"><img src="../images/next.png" alt="Next"></a> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title"> +<a name="lambda.using_library"></a>Using the library</h3></div></div></div> +<div class="toc"><dl> +<dt><span class="section"><a href="using_library.html#lambda.introductory_examples">Introductory Examples</a></span></dt> +<dt><span class="section"><a href="using_library.html#lambda.parameter_and_return_types">Parameter and return types of lambda functors</a></span></dt> +<dt><span class="section"><a href="using_library.html#lambda.actual_arguments_to_lambda_functors">About actual arguments to lambda functors</a></span></dt> +<dt><span class="section"><a href="using_library.html#lambda.storing_bound_arguments">Storing bound arguments in lambda functions</a></span></dt> +</dl></div> +<p> +The purpose of this section is to introduce the basic functionality of the library. +There are quite a lot of exceptions and special cases, but discussion of them is postponed until later sections. + + + </p> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.introductory_examples"></a>Introductory Examples</h4></div></div></div> +<p> + In this section we give basic examples of using BLL lambda expressions in STL algorithm invocations. + We start with some simple expressions and work up. + First, we initialize the elements of a container, say, a <code class="literal">list</code>, to the value <code class="literal">1</code>: + + + </p> +<pre class="programlisting"> +list<int> v(10); +for_each(v.begin(), v.end(), _1 = 1);</pre> +<p> + + The expression <code class="literal">_1 = 1</code> creates a lambda functor which assigns the value <code class="literal">1</code> to every element in <code class="literal">v</code>.<sup>[<a name="id1223205" href="#ftn.id1223205">1</a>]</sup></p> +<p> + Next, we create a container of pointers and make them point to the elements in the first container <code class="literal">v</code>: + + </p> +<pre class="programlisting"> +vector<int*> vp(10); +transform(v.begin(), v.end(), vp.begin(), &_1);</pre> +<p> + +The expression <code class="literal">&_1</code> creates a function object for getting the address of each element in <code class="literal">v</code>. +The addresses get assigned to the corresponding elements in <code class="literal">vp</code>. + </p> +<p> + The next code fragment changes the values in <code class="literal">v</code>. + For each element, the function <code class="literal">foo</code> is called. +The original value of the element is passed as an argument to <code class="literal">foo</code>. +The result of <code class="literal">foo</code> is assigned back to the element: + + + </p> +<pre class="programlisting"> +int foo(int); +for_each(v.begin(), v.end(), _1 = bind(foo, _1));</pre> +<p> + The next step is to sort the elements of <code class="literal">vp</code>: + + </p> +<pre class="programlisting">sort(vp.begin(), vp.end(), *_1 > *_2);</pre> +<p> + + In this call to <code class="literal">sort</code>, we are sorting the elements by their contents in descending order. + </p> +<p> + Finally, the following <code class="literal">for_each</code> call outputs the sorted content of <code class="literal">vp</code> separated by line breaks: + +</p> +<pre class="programlisting"> +for_each(vp.begin(), vp.end(), cout << *_1 << '\n'); +</pre> +<p> + +Note that a normal (non-lambda) expression as subexpression of a lambda expression is evaluated immediately. +This may cause surprises. +For instance, if the previous example is rewritten as +</p> +<pre class="programlisting"> +for_each(vp.begin(), vp.end(), cout << '\n' << *_1); +</pre> +<p> +the subexpression <code class="literal">cout << '\n'</code> is evaluated immediately and the effect is to output a single line break, followed by the elements of <code class="literal">vp</code>. +The BLL provides functions <code class="literal">constant</code> and <code class="literal">var</code> to turn constants and, respectively, variables into lambda expressions, and can be used to prevent the immediate evaluation of subexpressions: +</p> +<pre class="programlisting"> +for_each(vp.begin(), vp.end(), cout << constant('\n') << *_1); +</pre> +<p> +These functions are described more thoroughly in <a href="le_in_details.html#lambda.delaying_constants_and_variables" title="Delaying constants and variables">the section called “Delaying constants and variables”</a></p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.parameter_and_return_types"></a>Parameter and return types of lambda functors</h4></div></div></div> +<p> + During the invocation of a lambda functor, the actual arguments are substituted for the placeholders. + The placeholders do not dictate the type of these actual arguments. + The basic rule is that a lambda function can be called with arguments of any types, as long as the lambda expression with substitutions performed is a valid C++ expression. + As an example, the expression + <code class="literal">_1 + _2</code> creates a binary lambda functor. + It can be called with two objects of any types <code class="literal">A</code> and <code class="literal">B</code> for which <code class="literal">operator+(A,B)</code> is defined (and for which BLL knows the return type of the operator, see below). + </p> +<p> + C++ lacks a mechanism to query a type of an expression. + However, this precise mechanism is crucial for the implementation of C++ lambda expressions. + Consequently, BLL includes a somewhat complex type deduction system which uses a set of traits classes for deducing the resulting type of lambda functions. + It handles expressions where the operands are of built-in types and many of the expressions with operands of standard library types. + Many of the user defined types are covered as well, particularly if the user defined operators obey normal conventions in defining the return types. + </p> +<p> + There are, however, cases when the return type cannot be deduced. For example, suppose you have defined: + + </p> +<pre class="programlisting">C operator+(A, B);</pre> +<p> + + The following lambda function invocation fails, since the return type cannot be deduced: + + </p> +<pre class="programlisting">A a; B b; (_1 + _2)(a, b);</pre> +<p> + There are two alternative solutions to this. + The first is to extend the BLL type deduction system to cover your own types (see <a href="extending.html" title="Extending return type deduction system">the section called “Extending return type deduction system”</a>). + The second is to use a special lambda expression (<code class="literal">ret</code>) which defines the return type in place (see <a href="le_in_details.html#lambda.overriding_deduced_return_type" title="Overriding the deduced return type">the section called “Overriding the deduced return type”</a>): + + </p> +<pre class="programlisting">A a; B b; ret<C>(_1 + _2)(a, b);</pre> +<p> + For bind expressions, the return type can be defined as a template argument of the bind function as well: + </p> +<pre class="programlisting">bind<int>(foo, _1, _2);</pre> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.actual_arguments_to_lambda_functors"></a>About actual arguments to lambda functors</h4></div></div></div> +<p>A general restriction for the actual arguments is that they cannot be non-const rvalues. + For example: + +</p> +<pre class="programlisting"> +int i = 1; int j = 2; +(_1 + _2)(i, j); // ok +(_1 + _2)(1, 2); // error (!) +</pre> +<p> + + This restriction is not as bad as it may look. + Since the lambda functors are most often called inside STL-algorithms, + the arguments originate from dereferencing iterators and the dereferencing operators seldom return rvalues. + And for the cases where they do, there are workarounds discussed in +<a href="le_in_details.html#lambda.rvalues_as_actual_arguments" title="Rvalues as actual arguments to lambda functors">the section called “Rvalues as actual arguments to lambda functors”</a>. + + + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h4 class="title"> +<a name="lambda.storing_bound_arguments"></a>Storing bound arguments in lambda functions</h4></div></div></div> +<p> + +By default, temporary const copies of the bound arguments are stored +in the lambda functor. + +This means that the value of a bound argument is fixed at the time of the +creation of the lambda function and remains constant during the lifetime +of the lambda function object. +For example: +</p> +<pre class="programlisting"> +int i = 1; +(_1 = 2, _1 + i)(i); +</pre> +<p> +The comma operator is overloaded to combine lambda expressions into a sequence; +the resulting unary lambda functor first assigns 2 to its argument, +then adds the value of <code class="literal">i</code> to it. +The value of the expression in the last line is 3, not 4. +In other words, the lambda expression that is created is +<code class="literal">lambda x.(x = 2, x + 1)</code> rather than +<code class="literal">lambda x.(x = 2, x + i)</code>. + +</p> +<p> + +As said, this is the default behavior for which there are exceptions. +The exact rules are as follows: + +</p> +<div class="itemizedlist"><ul type="disc"> +<li> +<p> + +The programmer can control the storing mechanism with <code class="literal">ref</code> +and <code class="literal">cref</code> wrappers [<a href="../lambda.html#cit:boost::ref" title="[ref]"><span class="abbrev">ref</span></a>]. + +Wrapping an argument with <code class="literal">ref</code>, or <code class="literal">cref</code>, +instructs the library to store the argument as a reference, +or as a reference to const respectively. + +For example, if we rewrite the previous example and wrap the variable +<code class="literal">i</code> with <code class="literal">ref</code>, +we are creating the lambda expression <code class="literal">lambda x.(x = 2, x + i)</code> +and the value of the expression in the last line will be 4: + +</p> +<pre class="programlisting"> +i = 1; +(_1 = 2, _1 + ref(i))(i); +</pre> +<p> + +Note that <code class="literal">ref</code> and <code class="literal">cref</code> are different +from <code class="literal">var</code> and <code class="literal">constant</code>. + +While the latter ones create lambda functors, the former do not. +For example: + +</p> +<pre class="programlisting"> +int i; +var(i) = 1; // ok +ref(i) = 1; // not ok, ref(i) is not a lambda functor +</pre> +<p> + +The functions <code class="literal">ref</code> and <code class="literal">cref</code> mostly +exist for historical reasons, +and <code class="literal">ref</code> can always +be replaced with <code class="literal">var</code>, and <code class="literal">cref</code> with +<code class="literal">constant_ref</code>. +See <a href="le_in_details.html#lambda.delaying_constants_and_variables" title="Delaying constants and variables">the section called “Delaying constants and variables”</a> for details. +The <code class="literal">ref</code> and <code class="literal">cref</code> functions are +general purpose utility functions in Boost, and hence defined directly +in the <code class="literal">boost</code> namespace. + +</p> +</li> +<li><p> +Array types cannot be copied, they are thus stored as const reference by default. +</p></li> +<li> +<p> +For some expressions it makes more sense to store the arguments as references. + +For example, the obvious intention of the lambda expression +<code class="literal">i += _1</code> is that calls to the lambda functor affect the +value of the variable <code class="literal">i</code>, +rather than some temporary copy of it. + +As another example, the streaming operators take their leftmost argument +as non-const references. + +The exact rules are: + +</p> +<div class="itemizedlist"><ul type="circle"> +<li><p>The left argument of compound assignment operators (<code class="literal">+=</code>, <code class="literal">*=</code>, etc.) are stored as references to non-const.</p></li> +<li><p>If the left argument of <code class="literal"><<</code> or <code class="literal">>></code> operator is derived from an instantiation of <code class="literal">basic_ostream</code> or respectively from <code class="literal">basic_istream</code>, the argument is stored as a reference to non-const. +For all other types, the argument is stored as a copy. +</p></li> +<li><p> +In pointer arithmetic expressions, non-const array types are stored as non-const references. +This is to prevent pointer arithmetic making non-const arrays const. + +</p></li> +</ul></div> +</li> +</ul></div> +</div> +<div class="footnotes"> +<br><hr width="100" align="left"> +<div class="footnote"><p><sup>[<a name="ftn.id1223205" href="#id1223205">1</a>] </sup> +Strictly taken, the C++ standard defines <code class="literal">for_each</code> as a <span class="emphasis"><em>non-modifying sequence operation</em></span>, and the function object passed to <code class="literal">for_each</code> should not modify its argument. +The requirements for the arguments of <code class="literal">for_each</code> are unnecessary strict, since as long as the iterators are <span class="emphasis"><em>mutable</em></span>, <code class="literal">for_each</code> accepts a function object that can have side-effects on their argument. +Nevertheless, it is straightforward to provide another function template with the functionality of<code class="literal">std::for_each</code> but more fine-grained requirements for its arguments. +</p></div> +</div> +</div> +<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> +<td align="left"></td> +<td align="right"><small>Copyright © 1999-2004 Jaakko Järvi, Gary Powell</small></td> +</tr></table> +<hr> +<div class="spirit-nav"> +<a accesskey="p" href="s03.html"><img src="../images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="le_in_details.html"><img src="../images/next.png" alt="Next"></a> +</div> +</body> +</html> |