the-lambda-metafunction.html 6.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <!-- Copyright Aleksey Gurtovoy 2006. Distributed under the Boost -->
  5. <!-- Software License, Version 1.0. (See accompanying -->
  6. <!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
  7. <head>
  8. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  9. <meta name="generator" content="Docutils 0.3.6: http://docutils.sourceforge.net/" />
  10. <title>THE BOOST MPL LIBRARY: The lambda Metafunction</title>
  11. <link rel="stylesheet" href="../style.css" type="text/css" />
  12. </head>
  13. <body class="docframe">
  14. <table class="header"><tr class="header"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./handling-placeholders.html" class="navigation-link">Prev</a>&nbsp;<a href="./the-apply-metafunction.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group">Back&nbsp;<a href="./the-apply-metafunction.html" class="navigation-link">Along</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./handling-placeholders.html" class="navigation-link">Up</a>&nbsp;<a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td>
  15. <td class="header-group page-location"><a href="../index.html" class="navigation-link">Front Page</a> / <a href="./tutorial-metafunctions.html" class="navigation-link">Tutorial: Metafunctions and Higher-Order Metaprogramming</a> / <a href="./handling-placeholders.html" class="navigation-link">Handling Placeholders</a> / <a href="./the-lambda-metafunction.html" class="navigation-link">The lambda Metafunction</a></td>
  16. </tr></table><div class="header-separator"></div>
  17. <div class="section" id="the-lambda-metafunction">
  18. <h1><a class="toc-backref" href="./handling-placeholders.html#id49" name="the-lambda-metafunction">The <tt class="literal"><span class="pre">lambda</span></tt> Metafunction</a></h1>
  19. <p>We can <em>generate</em> a metafunction class from
  20. <tt class="literal"><span class="pre">boost::add_pointer&lt;_1&gt;</span></tt>, using MPL's <tt class="literal"><span class="pre">lambda</span></tt> metafunction:</p>
  21. <pre class="literal-block">
  22. template &lt;class X&gt;
  23. struct two_pointers
  24. : twice&lt;<strong>typename mpl::lambda&lt;boost::add_pointer&lt;_1&gt; &gt;::type</strong>, X&gt;
  25. {};
  26. BOOST_STATIC_ASSERT((
  27. boost::is_same&lt;
  28. two_pointers&lt;int&gt;::type
  29. , int**
  30. &gt;::value
  31. ));
  32. </pre>
  33. <!-- @ prefix.append('#include <boost/mpl/lambda.hpp>')
  34. compile('all') -->
  35. <p>We'll refer to metafunction classes like <tt class="literal"><span class="pre">add_pointer_f</span></tt> and
  36. placeholder expressions like <tt class="literal"><span class="pre">boost::add_pointer&lt;_1&gt;</span></tt>
  37. as <strong>lambda expressions</strong>. The term, meaning &quot;unnamed function
  38. object,&quot; was introduced in the 1930s by the logician Alonzo Church
  39. as part of a fundamental theory of computation he called the
  40. <em>lambda-calculus</em>. <a class="footnote-reference" href="#lambda" id="id10" name="id10">[4]</a> MPL uses the somewhat obscure word
  41. <tt class="literal"><span class="pre">lambda</span></tt> because of its well-established precedent in functional
  42. programming languages.</p>
  43. <table class="footnote" frame="void" id="lambda" rules="none">
  44. <colgroup><col class="label" /><col /></colgroup>
  45. <tbody valign="top">
  46. <tr><td class="label"><a class="fn-backref" href="#id10" name="lambda">[4]</a></td><td>See <a class="reference" href="http://en.wikipedia.org/wiki/Lambda_calculus" target="_top">http://en.wikipedia.org/wiki/Lambda_calculus</a> for
  47. an in-depth treatment, including a reference to Church's paper
  48. proving that the equivalence of lambda expressions is in general
  49. not decidable.</td></tr>
  50. </tbody>
  51. </table>
  52. <p>Although its primary purpose is to turn placeholder expressions
  53. into metafunction classes, <tt class="literal"><span class="pre">mpl::lambda</span></tt> can accept any lambda
  54. expression, even if it's already a metafunction class. In that
  55. case, <tt class="literal"><span class="pre">lambda</span></tt> returns its argument unchanged. MPL algorithms
  56. like <tt class="literal"><span class="pre">transform</span></tt> call <tt class="literal"><span class="pre">lambda</span></tt> internally, before invoking the
  57. resulting metafunction class, so that they work equally well with
  58. either kind of lambda expression. We can apply the same strategy
  59. to <tt class="literal"><span class="pre">twice</span></tt>:</p>
  60. <pre class="literal-block">
  61. template &lt;class F, class X&gt;
  62. struct twice
  63. : apply1&lt;
  64. typename mpl::lambda&lt;F&gt;::type
  65. , typename apply1&lt;
  66. typename mpl::lambda&lt;F&gt;::type
  67. , X
  68. &gt;::type
  69. &gt;
  70. {};
  71. </pre>
  72. <p>Now we can use <tt class="literal"><span class="pre">twice</span></tt> with metafunction classes <em>and</em>
  73. placeholder expressions:</p>
  74. <pre class="literal-block">
  75. int* x;
  76. twice&lt;<strong>add_pointer_f</strong>, int&gt;::type p = &amp;x;
  77. twice&lt;<strong>boost::add_pointer&lt;_1&gt;</strong>, int&gt;::type q = &amp;x;
  78. </pre>
  79. <!-- @ stack[-2:] = [ apply1, stack[-2], add_pointer_f, stack[-1]]
  80. compile('all') -->
  81. </div>
  82. <div class="footer-separator"></div>
  83. <table class="footer"><tr class="footer"><td class="header-group navigation-bar"><span class="navigation-group"><a href="./handling-placeholders.html" class="navigation-link">Prev</a>&nbsp;<a href="./the-apply-metafunction.html" class="navigation-link">Next</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group">Back&nbsp;<a href="./the-apply-metafunction.html" class="navigation-link">Along</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./handling-placeholders.html" class="navigation-link">Up</a>&nbsp;<a href="../index.html" class="navigation-link">Home</a></span><span class="navigation-group-separator">&nbsp;|&nbsp;</span><span class="navigation-group"><a href="./tutorial_toc.html" class="navigation-link">Full TOC</a></span></td>
  84. </tr></table></body>
  85. </html>