• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Using the library</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../lambda.html" title="Chapter 20. Boost.Lambda">
10<link rel="prev" href="s03.html" title="Introduction">
11<link rel="next" href="le_in_details.html" title="Lambda expressions in details">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="s03.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="le_in_details.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="lambda.using_library"></a>Using the library</h2></div></div></div>
29<div class="toc"><dl class="toc">
30<dt><span class="section"><a href="using_library.html#lambda.introductory_examples">Introductory Examples</a></span></dt>
31<dt><span class="section"><a href="using_library.html#lambda.parameter_and_return_types">Parameter and return types of lambda functors</a></span></dt>
32<dt><span class="section"><a href="using_library.html#lambda.actual_arguments_to_lambda_functors">About actual arguments to lambda functors</a></span></dt>
33<dt><span class="section"><a href="using_library.html#lambda.storing_bound_arguments">Storing bound arguments in lambda functions</a></span></dt>
34</dl></div>
35<p>
36The purpose of this section is to introduce the basic functionality of the library.
37There are quite a lot of exceptions and special cases, but discussion of them is postponed until later sections.
38
39
40    </p>
41<div class="section">
42<div class="titlepage"><div><div><h3 class="title">
43<a name="lambda.introductory_examples"></a>Introductory Examples</h3></div></div></div>
44<p>
45	In this section we give basic examples of using BLL lambda expressions in STL algorithm invocations.
46	We start with some simple expressions and work up.
47	First, we initialize the elements of a container, say, a <code class="literal">list</code>, to the value <code class="literal">1</code>:
48
49
50	</p>
51<pre class="programlisting">
52list&lt;int&gt; v(10);
53for_each(v.begin(), v.end(), _1 = 1);</pre>
54<p>
55
56	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>.<a href="#ftn.id-1.3.21.6.3.2.7" class="footnote" name="id-1.3.21.6.3.2.7"><sup class="footnote">[7]</sup></a>
57      </p>
58<p>
59	Next, we create a container of pointers and make them point to the elements in the first container <code class="literal">v</code>:
60
61	</p>
62<pre class="programlisting">
63vector&lt;int*&gt; vp(10);
64transform(v.begin(), v.end(), vp.begin(), &amp;_1);</pre>
65<p>
66
67The expression <code class="literal">&amp;_1</code> creates a function object for getting the address of each element in <code class="literal">v</code>.
68The addresses get assigned to the corresponding elements in <code class="literal">vp</code>.
69      </p>
70<p>
71	The next code fragment changes the values in <code class="literal">v</code>.
72	For each element, the function <code class="literal">foo</code> is called.
73The original value of the element is passed as an argument to <code class="literal">foo</code>.
74The result of <code class="literal">foo</code> is assigned back to the element:
75
76
77	</p>
78<pre class="programlisting">
79int foo(int);
80for_each(v.begin(), v.end(), _1 = bind(foo, _1));</pre>
81<p>
82      </p>
83<p>
84	The next step is to sort the elements of <code class="literal">vp</code>:
85
86	</p>
87<pre class="programlisting">sort(vp.begin(), vp.end(), *_1 &gt; *_2);</pre>
88<p>
89
90	In this call to <code class="literal">sort</code>, we are sorting the elements by their contents in descending order.
91      </p>
92<p>
93	Finally, the following <code class="literal">for_each</code> call outputs the sorted content of <code class="literal">vp</code> separated by line breaks:
94
95</p>
96<pre class="programlisting">
97for_each(vp.begin(), vp.end(), cout &lt;&lt; *_1 &lt;&lt; '\n');
98</pre>
99<p>
100
101Note that a normal (non-lambda) expression as subexpression of a lambda expression is evaluated immediately.
102This may cause surprises.
103For instance, if the previous example is rewritten as
104</p>
105<pre class="programlisting">
106for_each(vp.begin(), vp.end(), cout &lt;&lt; '\n' &lt;&lt; *_1);
107</pre>
108<p>
109the subexpression <code class="literal">cout &lt;&lt; '\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>.
110The 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:
111</p>
112<pre class="programlisting">
113for_each(vp.begin(), vp.end(), cout &lt;&lt; constant('\n') &lt;&lt; *_1);
114</pre>
115<p>
116These functions are described more thoroughly in <a class="xref" href="le_in_details.html#lambda.delaying_constants_and_variables" title="Delaying constants and variables">the section called “Delaying constants and variables”</a>
117
118</p>
119</div>
120<div class="section">
121<div class="titlepage"><div><div><h3 class="title">
122<a name="lambda.parameter_and_return_types"></a>Parameter and return types of lambda functors</h3></div></div></div>
123<p>
124	During the invocation of a lambda functor, the actual arguments are substituted for the placeholders.
125	The placeholders do not dictate the type of these actual arguments.
126	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.
127	As an example, the expression
128	<code class="literal">_1 + _2</code> creates a binary lambda functor.
129	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).
130      </p>
131<p>
132	C++ lacks a mechanism to query a type of an expression.
133	However, this precise mechanism is crucial for the implementation of C++ lambda expressions.
134	Consequently, BLL includes a somewhat complex type deduction system which uses a set of traits classes for deducing the resulting type of lambda functions.
135	It handles expressions where the operands are of built-in types and many of the expressions with operands of standard library types.
136	Many of the user defined types are covered as well, particularly if the user defined operators obey normal conventions in defining the return types.
137      </p>
138<p>
139	There are, however, cases when the return type cannot be deduced. For example, suppose you have defined:
140
141	</p>
142<pre class="programlisting">C operator+(A, B);</pre>
143<p>
144
145	The following lambda function invocation fails, since the return type cannot be deduced:
146
147	</p>
148<pre class="programlisting">A a; B b; (_1 + _2)(a, b);</pre>
149<p>
150      </p>
151<p>
152	There are two alternative solutions to this.
153	The first is to extend the BLL type deduction system to cover your own types (see <a class="xref" href="extending.html" title="Extending return type deduction system">the section called “Extending return type deduction system”</a>).
154	The second is to use a special lambda expression (<code class="literal">ret</code>) which defines the return type in place (see <a class="xref" 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>):
155
156	</p>
157<pre class="programlisting">A a; B b; ret&lt;C&gt;(_1 + _2)(a, b);</pre>
158<p>
159      </p>
160<p>
161	For bind expressions, the return type can be defined as a template argument of the bind function as well:
162	</p>
163<pre class="programlisting">bind&lt;int&gt;(foo, _1, _2);</pre>
164<p>
165
166
167      </p>
168</div>
169<div class="section">
170<div class="titlepage"><div><div><h3 class="title">
171<a name="lambda.actual_arguments_to_lambda_functors"></a>About actual arguments to lambda functors</h3></div></div></div>
172<p>A general restriction for the actual arguments is that they cannot be non-const rvalues.
173	For example:
174
175</p>
176<pre class="programlisting">
177int i = 1; int j = 2;
178(_1 + _2)(i, j); // ok
179(_1 + _2)(1, 2); // error (!)
180</pre>
181<p>
182
183	This restriction is not as bad as it may look.
184	Since the lambda functors are most often called inside STL-algorithms,
185	the arguments originate from dereferencing iterators and the dereferencing operators seldom return rvalues.
186	And for the cases where they do, there are workarounds discussed in
187<a class="xref" 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>.
188
189
190      </p>
191</div>
192<div class="section">
193<div class="titlepage"><div><div><h3 class="title">
194<a name="lambda.storing_bound_arguments"></a>Storing bound arguments in lambda functions</h3></div></div></div>
195<p>
196
197By default, temporary const copies of the bound arguments are stored
198in the lambda functor.
199
200This means that the value of a bound argument is fixed at the time of the
201creation of the lambda function and remains constant during the lifetime
202of the lambda function object.
203For example:
204</p>
205<pre class="programlisting">
206int i = 1;
207(_1 = 2, _1 + i)(i);
208</pre>
209<p>
210The comma operator is overloaded to combine lambda expressions into a sequence;
211the resulting unary lambda functor first assigns 2 to its argument,
212then adds the value of <code class="literal">i</code> to it.
213The value of the expression in the last line is 3, not 4.
214In other words, the lambda expression that is created is
215<code class="literal">lambda x.(x = 2, x + 1)</code> rather than
216<code class="literal">lambda x.(x = 2, x + i)</code>.
217
218</p>
219<p>
220
221As said, this is the default behavior for which there are exceptions.
222The exact rules are as follows:
223
224</p>
225<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
226<li class="listitem">
227<p>
228
229The programmer can control the storing mechanism with <code class="literal">ref</code>
230and <code class="literal">cref</code> wrappers <a class="xref" href="../lambda.html#cit:boost::ref" title="Boost ref">[<abbr class="abbrev">ref</abbr>]</a>.
231
232Wrapping an argument with <code class="literal">ref</code>, or <code class="literal">cref</code>,
233instructs the library to store the argument as a reference,
234or as a reference to const respectively.
235
236For example, if we rewrite the previous example and wrap the variable
237<code class="literal">i</code> with <code class="literal">ref</code>,
238we are creating the lambda expression <code class="literal">lambda x.(x = 2, x + i)</code>
239and the value of the expression in the last line will be 4:
240
241</p>
242<pre class="programlisting">
243i = 1;
244(_1 = 2, _1 + ref(i))(i);
245</pre>
246<p>
247
248Note that <code class="literal">ref</code> and <code class="literal">cref</code> are different
249from <code class="literal">var</code> and <code class="literal">constant</code>.
250
251While the latter ones create lambda functors, the former do not.
252For example:
253
254</p>
255<pre class="programlisting">
256int i;
257var(i) = 1; // ok
258ref(i) = 1; // not ok, ref(i) is not a lambda functor
259</pre>
260<p>
261
262The functions <code class="literal">ref</code> and <code class="literal">cref</code> mostly
263exist for historical reasons,
264and <code class="literal">ref</code> can always
265be replaced with <code class="literal">var</code>, and <code class="literal">cref</code> with
266<code class="literal">constant_ref</code>.
267See <a class="xref" 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.
268The <code class="literal">ref</code> and <code class="literal">cref</code> functions are
269general purpose utility functions in Boost, and hence defined directly
270in the <code class="literal">boost</code> namespace.
271
272</p>
273</li>
274<li class="listitem"><p>
275Array types cannot be copied, they are thus stored as const reference by default.
276</p></li>
277<li class="listitem">
278<p>
279For some expressions it makes more sense to store the arguments as references.
280
281For example, the obvious intention of the lambda expression
282<code class="literal">i += _1</code> is that calls to the lambda functor affect the
283value of the variable <code class="literal">i</code>,
284rather than some temporary copy of it.
285
286As another example, the streaming operators take their leftmost argument
287as non-const references.
288
289The exact rules are:
290
291</p>
292<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
293<li class="listitem"><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>
294<li class="listitem"><p>If the left argument of <code class="literal">&lt;&lt;</code> or <code class="literal">&gt;&gt;</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.
295For all other types, the argument is stored as a copy.
296</p></li>
297<li class="listitem"><p>
298In pointer arithmetic expressions, non-const array types are stored as non-const references.
299This is to prevent pointer arithmetic making non-const arrays const.
300
301</p></li>
302</ul></div>
303<p>
304
305</p>
306</li>
307</ul></div>
308<p>
309</p>
310</div>
311<div class="footnotes">
312<br><hr style="width:100; text-align:left;margin-left: 0">
313<div id="ftn.id-1.3.21.6.3.2.7" class="footnote"><p><a href="#id-1.3.21.6.3.2.7" class="para"><sup class="para">[7] </sup></a>
314Strictly 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.
315The 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.
316Nevertheless, 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.
317</p></div>
318</div>
319</div>
320<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
321<td align="left"></td>
322<td align="right"><div class="copyright-footer">Copyright © 1999-2004 Jaakko Järvi, Gary Powell<p>Use, modification and distribution is subject to the Boost
323    Software License, Version 1.0. (See accompanying file
324    <code class="filename">LICENSE_1_0.txt</code> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)</p>
325</div></td>
326</tr></table>
327<hr>
328<div class="spirit-nav">
329<a accesskey="p" href="s03.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../lambda.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="le_in_details.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
330</div>
331</body>
332</html>
333