PageRenderTime 41ms CodeModel.GetById 26ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 0ms

/Src/Dependencies/Boost/libs/phoenix/doc/html/phoenix/modules/scope/lambda.html

http://hadesmem.googlecode.com/
HTML | 194 lines | 190 code | 4 blank | 0 comment | 0 complexity | 83f3d79780d615a361e25df558df653f MD5 | raw file
  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.76.1">
  7<link rel="home" href="../../../index.html" title="Chapter&#160;1.&#160;Phoenix 3.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
 88</span><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 Joel de Guzman, Dan Marsden, Thomas Heller<p>
184        Distributed under the Boost Software License, Version 1.0. (See accompanying
185        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>)
186      </p>
187</div></td>
188</tr></table>
189<hr>
190<div class="spirit-nav">
191<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>
192</div>
193</body>
194</html>