quick_start.html 7.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <html>
  2. <head>
  3. <!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
  4. <title>Quick start</title>
  5. <link rel="stylesheet" href="theme/style.css" type="text/css">
  6. <link rel="prev" href="introduction.html">
  7. <link rel="next" href="basic_concepts.html">
  8. </head>
  9. <body>
  10. <table width="100%" height="48" border="0" background="theme/bkd2.gif" cellspacing="2">
  11. <tr>
  12. <td width="10">
  13. </td>
  14. <td width="85%">
  15. <font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Quick start</b></font>
  16. </td>
  17. <td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" align="right" border="0"></a></td>
  18. </tr>
  19. </table>
  20. <br>
  21. <table border="0">
  22. <tr>
  23. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  24. <td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
  25. <td width="20"><a href="basic_concepts.html"><img src="theme/r_arr.gif" border="0"></a></td>
  26. </tr>
  27. </table>
  28. <p>
  29. To get a first glimpse on what the Phoenix framework offers, let us start with an example. We want to find the first odd number in an STL container.</p>
  30. <p>
  31. 1) Normally we use a functor or a function pointer and pass that in to STL's find_if generic function (sample1.cpp):</p>
  32. <p>
  33. Write a function:</p>
  34. <code><pre>
  35. <span class=keyword>bool
  36. </span><span class=identifier>is_odd</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>arg1</span><span class=special>)
  37. {
  38. </span><span class=keyword>return </span><span class=identifier>arg1 </span><span class=special>% </span><span class=number>2 </span><span class=special>== </span><span class=number>1</span><span class=special>;
  39. }
  40. </span></pre></code>
  41. <p>
  42. Pass a pointer to the function to STL's find_if generic function:</p>
  43. <code><pre>
  44. <span class=identifier>find_if</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>(), &amp;</span><span class=identifier>is_odd</span><span class=special>)
  45. </span></pre></code>
  46. <p>
  47. 2) Using Phoenix, the same can be achieved directly with a one- liner (sample2.cpp):</p>
  48. <code><pre>
  49. <span class=identifier>find_if</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>arg1 </span><span class=special>% </span><span class=number>2 </span><span class=special>== </span><span class=number>1</span><span class=special>)
  50. </span></pre></code>
  51. <p>
  52. The expression &quot;arg1 % 2 == 1&quot; automagically creates a functor with the expected behavior. In FP, this unnamed function is called a lambda function. Unlike 1, the function pointer version, which is monomorphic (expects and works only with a fixed type int argument), the Phoenix version is completely polymorphic and works with any container (of ints, of doubles, of complex, etc.) as long as its elements can handle the &quot;arg1 % 2 == 1&quot; expression.</p>
  53. <p>
  54. 3) Write a polymorphic functor using Phoenix (sample3.cpp)</p>
  55. <code><pre>
  56. <span class=keyword>struct </span><span class=identifier>is_odd_ </span><span class=special>{
  57. </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ArgT</span><span class=special>&gt;
  58. </span><span class=keyword>struct </span><span class=identifier>result </span><span class=special>{ </span><span class=keyword>typedef </span><span class=keyword>bool </span><span class=identifier>type</span><span class=special>; };
  59. </span><span class=keyword>template </span><span class=special>&lt;</span><span class=keyword>typename </span><span class=identifier>ArgT</span><span class=special>&gt;
  60. </span><span class=keyword>bool </span><span class=keyword>operator</span><span class=special>()(</span><span class=identifier>ArgT </span><span class=identifier>arg1</span><span class=special>) </span><span class=keyword>const
  61. </span><span class=special>{ </span><span class=keyword>return </span><span class=identifier>arg1 </span><span class=special>% </span><span class=number>2 </span><span class=special>== </span><span class=number>1</span><span class=special>; }
  62. };
  63. </span><span class=identifier>function</span><span class=special>&lt;</span><span class=identifier>is_odd_</span><span class=special>&gt; </span><span class=identifier>is_odd</span><span class=special>;
  64. </span></pre></code>
  65. <p>
  66. Call the lazy is_odd function:</p>
  67. <code><pre>
  68. <span class=identifier>find_if</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>is_odd</span><span class=special>(</span><span class=identifier>arg1</span><span class=special>))
  69. </span></pre></code>
  70. <p>
  71. is_odd_ is the actual functor. It has been proxied in function&lt;is_odd_&gt; by is_odd (note no trailing underscore) which makes it a lazy function. is_odd_::operator() is the main function body. is_odd_::result is a type computer that answers the question &quot;What should be our return type given an argument of type ArgT?&quot;.</p>
  72. <p>
  73. Like 2, and unlike 1, function pointers or plain C++ functors, is_odd is a true lazy, polymorphic functor (rank-2 polymorphic functoid, in <a href="https://people.cs.umass.edu/~yannis/fc++/">
  74. FC++</a> jargon). The Phoenix functor version is fully polymorphic and works with any container (of ints, of doubles, of complex, etc.) as long as its elements can handle the &quot;arg1 % 2 == 1&quot; expression. However, unlike 2, this is more efficient and has less overhead especially when dealing with much more complex functions.</p>
  75. <p>
  76. This is just the tip of the iceberg. There are more nifty things you can do with the framework. There are quite interesting concepts such as rank-2 polymorphic lazy functions, lazy statements, binders etc; enough to whet the appetite of anyone wishing to squeeze more power from C++.</p>
  77. <table border="0">
  78. <tr>
  79. <td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
  80. <td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
  81. <td width="20"><a href="basic_concepts.html"><img src="theme/r_arr.gif" border="0"></a></td>
  82. </tr>
  83. </table>
  84. <br>
  85. <hr size="1">
  86. <p class="copyright">Copyright &copy; 2001-2002 Joel de Guzman<br>
  87. <br>
  88. <font size="2">Use, modification and distribution is subject to the Boost Software
  89. License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  90. http://www.boost.org/LICENSE_1_0.txt) </font> </p>
  91. </body>
  92. </html>