]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/phoenix/doc/html/phoenix/modules/scope/lambda.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / phoenix / doc / html / phoenix / modules / scope / lambda.html
CommitLineData
7c673cae
FG
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4<title>lambda</title>
5<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
7<link rel="home" href="../../../index.html" title="Chapter&#160;1.&#160;Phoenix 3.2.0">
8<link rel="up" href="../scope.html" title="Scope">
9<link rel="prev" href="let.html" title="let">
10<link rel="next" href="../bind.html" title="Bind">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%"><tr>
14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
15<td align="center"><a href="../../../../../../../index.html">Home</a></td>
16<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
20</tr></table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="let.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../scope.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="../bind.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
24</div>
25<div class="section">
26<div class="titlepage"><div><div><h4 class="title">
27<a name="phoenix.modules.scope.lambda"></a><a class="link" href="lambda.html" title="lambda">lambda</a>
28</h4></div></div></div>
29<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">phoenix</span><span class="special">/</span><span class="identifier">scope</span><span class="special">/</span><span class="identifier">lambda</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
30</pre>
31<p>
32 A lot of times, you'd want to write a lazy function that accepts one or
33 more functions (higher order functions). STL algorithms come to mind, for
34 example. Consider a lazy version of <code class="computeroutput"><span class="identifier">stl</span><span class="special">::</span><span class="identifier">for_each</span></code>:
35 </p>
36<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">for_each_impl</span>
37<span class="special">{</span>
38 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">C</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
39 <span class="keyword">struct</span> <span class="identifier">result</span>
40 <span class="special">{</span>
41 <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">type</span><span class="special">;</span>
42 <span class="special">};</span>
43
44 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">C</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
45 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">C</span><span class="special">&amp;</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">F</span> <span class="identifier">f</span><span class="special">)</span> <span class="keyword">const</span>
46 <span class="special">{</span>
47 <span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">f</span><span class="special">);</span>
48 <span class="special">}</span>
49<span class="special">};</span>
50
51<span class="identifier">function</span><span class="special">&lt;</span><span class="identifier">for_each_impl</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">for_each</span> <span class="special">=</span> <span class="identifier">for_each_impl</span><span class="special">();</span>
52</pre>
53<p>
54 Notice that the function accepts another function, <code class="computeroutput"><span class="identifier">f</span></code>
55 as an argument. The scope of this function, <code class="computeroutput"><span class="identifier">f</span></code>,
56 is limited within the <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>. When <code class="computeroutput"><span class="identifier">f</span></code>
57 is called inside <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span></code>, it exists in a new scope, along
58 with new arguments and, possibly, local variables. This new scope is not
59 at all related to the outer scopes beyond the <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>.
60 </p>
61<p>
62 Simple syntax:
63 </p>
64<pre class="programlisting"><span class="identifier">lambda</span>
65<span class="special">[</span>
66 <span class="identifier">lambda</span><span class="special">-</span><span class="identifier">body</span>
67<span class="special">]</span>
68</pre>
69<p>
70 Like <code class="computeroutput"><span class="identifier">let</span></code>, local variables
71 may be declared, allowing 1..N local variable declarations (where N ==
72 <code class="computeroutput"><span class="identifier">BOOST_PHOENIX_LOCAL_LIMIT</span></code>):
73 </p>
74<pre class="programlisting"><span class="identifier">lambda</span><span class="special">(</span><span class="identifier">local</span><span class="special">-</span><span class="identifier">declarations</span><span class="special">)</span>
75<span class="special">[</span>
76 <span class="identifier">lambda</span><span class="special">-</span><span class="identifier">body</span>
77<span class="special">]</span>
78</pre>
79<p>
80 The same restrictions apply with regard to scope and visibility. The RHS
81 (right hand side lambda-expression) of each local-declaration cannot refer
82 to any LHS local-id. The local-ids are not in scope yet; they will be in
83 scope only in the lambda-body:
84 </p>
85<pre class="programlisting"><span class="identifier">lambda</span><span class="special">(</span>
86 <span class="identifier">_a</span> <span class="special">=</span> <span class="number">1</span>
87 <span class="special">,</span> <span class="identifier">_b</span> <span class="special">=</span> <span class="identifier">_a</span> <span class="comment">// Error: _a is not in scope yet</span>
88<span class="special">)</span>
89</pre>
90<p>
91 See <a class="link" href="let.html#phoenix.modules.scope.let.visibility"><code class="computeroutput"><span class="identifier">let</span></code> Visibility</a> for more information.
92 </p>
93<p>
94 Example: Using our lazy <code class="computeroutput"><span class="identifier">for_each</span></code>
95 let's print all the elements in a container:
96 </p>
97<pre class="programlisting"><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">arg1</span><span class="special">,</span> <span class="identifier">lambda</span><span class="special">[</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">arg1</span><span class="special">])</span>
98</pre>
99<p>
100 As far as the arguments are concerned (arg1..argN), the scope in which
101 the lambda-body exists is totally new. The left <code class="computeroutput"><span class="identifier">arg1</span></code>
102 refers to the argument passed to <code class="computeroutput"><span class="identifier">for_each</span></code>
103 (a container). The right <code class="computeroutput"><span class="identifier">arg1</span></code>
104 refers to the argument passed by <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">for_each</span></code>
105 when we finally get to call <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code> in our <code class="computeroutput"><span class="identifier">for_each_impl</span></code>
106 above (a container element).
107 </p>
108<p>
109 Yet, we may wish to get information from outer scopes. While we do not
110 have access to arguments in outer scopes, what we still have is access
111 to local variables from outer scopes. We may only be able to pass argument
112 related information from outer <code class="computeroutput"><span class="identifier">lambda</span></code>
113 scopes through the local variables.
114 </p>
115<div class="note"><table border="0" summary="Note">
116<tr>
117<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
118<th align="left">Note</th>
119</tr>
120<tr><td align="left" valign="top"><p>
121 This is a crucial difference between <code class="computeroutput"><span class="identifier">let</span></code>
122 and <code class="computeroutput"><span class="identifier">lambda</span></code>: <code class="computeroutput"><span class="identifier">let</span></code> does not introduce new arguments;
123 <code class="computeroutput"><span class="identifier">lambda</span></code> does.
124 </p></td></tr>
125</table></div>
126<p>
127 Another example: Using our lazy <code class="computeroutput"><span class="identifier">for_each</span></code>,
128 and a lazy <code class="computeroutput"><span class="identifier">push_back</span></code>:
129 </p>
130<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">push_back_impl</span>
131<span class="special">{</span>
132 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">C</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
133 <span class="keyword">struct</span> <span class="identifier">result</span>
134 <span class="special">{</span>
135 <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">type</span><span class="special">;</span>
136 <span class="special">};</span>
137
138 <span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">C</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
139 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">C</span><span class="special">&amp;</span> <span class="identifier">c</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">)</span> <span class="keyword">const</span>
140 <span class="special">{</span>
141 <span class="identifier">c</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">x</span><span class="special">);</span>
142 <span class="special">}</span>
143<span class="special">};</span>
144
145<span class="identifier">function</span><span class="special">&lt;</span><span class="identifier">push_back_impl</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">push_back</span> <span class="special">=</span> <span class="identifier">push_back_impl</span><span class="special">();</span>
146</pre>
147<p>
148 write a lambda expression that accepts:
149 </p>
150<div class="orderedlist"><ol class="orderedlist" type="1">
151<li class="listitem">
152 a 2-dimensional container (e.g. <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;</span></code>)
153 </li>
154<li class="listitem">
155 a container element (e.g. <code class="computeroutput"><span class="keyword">int</span></code>)
156 </li>
157</ol></div>
158<p>
159 and pushes-back the element to each of the <code class="computeroutput"><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code>.
160 </p>
161<p>
162 Solution:
163 </p>
164<pre class="programlisting"><span class="identifier">for_each</span><span class="special">(</span><span class="identifier">arg1</span><span class="special">,</span>
165 <span class="identifier">lambda</span><span class="special">(</span><span class="identifier">_a</span> <span class="special">=</span> <span class="identifier">arg2</span><span class="special">)</span>
166 <span class="special">[</span>
167 <span class="identifier">push_back</span><span class="special">(</span><span class="identifier">arg1</span><span class="special">,</span> <span class="identifier">_a</span><span class="special">)</span>
168 <span class="special">]</span>
169<span class="special">)</span>
170</pre>
171<p>
172 Since we do not have access to the arguments of the outer scopes beyond
173 the lambda-body, we introduce a local variable <code class="computeroutput"><span class="identifier">_a</span></code>
174 that captures the second outer argument: <code class="computeroutput"><span class="identifier">arg2</span></code>.
175 Hence: _a = arg2. This local variable is visible inside the lambda scope.
176 </p>
177<p>
178 (See <a href="../../../../../example/lambda.cpp" target="_top">lambda.cpp</a>)
179 </p>
180</div>
181<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
182<td align="left"></td>
183<td align="right"><div class="copyright-footer">Copyright &#169; 2002-2005, 2010, 2014, 2015 Joel de Guzman, Dan Marsden, Thomas
184 Heller, John Fletcher<p>
185 Distributed under the Boost Software License, Version 1.0. (See accompanying
186 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
187 </p>
188</div></td>
189</tr></table>
190<hr>
191<div class="spirit-nav">
192<a accesskey="p" href="let.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../scope.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="../bind.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
193</div>
194</body>
195</html>