spirit/classic/phoenix/doc/quick_start.html
2019-04-22 23:27:49 +02:00

96 lines
7.0 KiB
HTML

<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Quick start</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="introduction.html">
<link rel="next" href="basic_concepts.html">
</head>
<body>
<table width="100%" height="48" border="0" background="theme/bkd2.gif" cellspacing="2">
<tr>
<td width="10">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Quick start</b></font>
</td>
<td width="112"><a href="http://spirit.sf.net"><img src="theme/spirit.gif" align="right" border="0"></a></td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_concepts.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
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>
<p>
1) Normally we use a functor or a function pointer and pass that in to STL's find_if generic function (sample1.cpp):</p>
<p>
Write a function:</p>
<code><pre>
<span class=keyword>bool
</span><span class=identifier>is_odd</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>arg1</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>;
}
</span></pre></code>
<p>
Pass a pointer to the function to STL's find_if generic function:</p>
<code><pre>
<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>)
</span></pre></code>
<p>
2) Using Phoenix, the same can be achieved directly with a one- liner (sample2.cpp):</p>
<code><pre>
<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>)
</span></pre></code>
<p>
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>
<p>
3) Write a polymorphic functor using Phoenix (sample3.cpp)</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>is_odd_ </span><span class=special>{
</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;
</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>; };
</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;
</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
</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>; }
};
</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>;
</span></pre></code>
<p>
Call the lazy is_odd function:</p>
<code><pre>
<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>))
</span></pre></code>
<p>
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>
<p>
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++/">
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>
<p>
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>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="introduction.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_concepts.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1">
<p class="copyright">Copyright &copy; 2001-2002 Joel de Guzman<br>
<br>
<font size="2">Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt) </font> </p>
</body>
</html>