96 lines
7.0 KiB
HTML
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>(), &</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 "arg1 % 2 == 1" 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 "arg1 % 2 == 1" 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><</span><span class=keyword>typename </span><span class=identifier>ArgT</span><span class=special>>
|
|
</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><</span><span class=keyword>typename </span><span class=identifier>ArgT</span><span class=special>>
|
|
</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><</span><span class=identifier>is_odd_</span><span class=special>> </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<is_odd_> 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 "What should be our return type given an argument of type ArgT?".</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 "arg1 % 2 == 1" 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 © 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>
|