2
0
mirror of https://github.com/boostorg/lambda.git synced 2026-01-22 17:22:48 +00:00
Files
lambda/doc/ar01s08.html
Jaakko Järvi f54bbdc1a7 added test coverage
[SVN r12904]
2002-02-22 19:43:42 +00:00

144 lines
8.1 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type"><title>8. Relation to other Boost libraries</title><meta name="generator" content="DocBook XSL Stylesheets V1.48"><link rel="home" href="index.html" title="
C++ BOOST
The Boost Lambda Library"><link rel="up" href="index.html" title="
C++ BOOST
The Boost Lambda Library"><link rel="previous" href="ar01s07.html" title="7. Practical considerations"><link rel="next" href="ar01s09.html" title="9. Contributors"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">8. Relation to other Boost libraries</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ar01s07.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ar01s09.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><h2 class="title" style="clear: both"><a name="id2807880"></a>8. Relation to other Boost libraries</h2></div></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2807887"></a>8.1. Boost Function</h3></div></div><p>Sometimes it is convenient to store lambda functors in variables.
However, the types of even the simplest lambda functors are long and unwieldy, and it is in general unfeasible to declare variables with lambda functor types.
<span class="emphasis"><i>The Boost Function library</i></span> [<a href="bi01.html#cit:boost::function" title="[function]">function</a>] defines wrappers for (almost) arbitrary function objects; and these wrappers have types that are easy to type out.
For example:
<pre class="programlisting">
int foo(float, char);
boost::function&lt;int, float, char&gt; f = foo;
boost::function&lt;int, int, int&gt; g = std::plus&lt;int&gt;();
</pre>
The return and parameter types of the wrapped function object must be written explicilty as template arguments to the wrapper template <tt>boost::function</tt>; even when lambda functors, which otherwise have generic parameters, are wrapped.
Wrapping a function object with <tt>boost::function</tt> introduces a performance cost comparable to virtual function dispatch, though virtual functions are not actually used.
</p><p>
Due to a technical conflict between the two libraries, lambda functors cannot be directly wrapped with <tt>boost::function</tt> (this may be resolved in the future).
However, applying the <tt>unlambda</tt> (see <a href="ar01s05.html#sect:unlambda" title="5.9.1.1. Unlambda">Section 5.9.1.1</a>) function to a lambda functor gives a function object that is compatible with <tt>boost::function</tt>.
For example:
<pre class="programlisting">
boost::function&lt;int, int, int&gt; f = unlambda(_1 + _2);
f(1, 2); // returns 3
</pre>
<pre class="programlisting">
int i = 1;
boost::function&lt;int&amp;, int&amp;&gt; g = unlambda(_1 += 10);
g(i); // i == 11;
</pre>
Note that storing lambda functors inside <tt>boost::function</tt> introduces a danger.
Certain types of lambda functors may store references to the bound arguments, instead as taking copies of the arguments of the lambda expression.
When temporary lambda functor objects are used
in STL algorithm invocations this is always safe, as the lambda functor gets destructed immediately after the STL algortihm invocation is completed.
However, a lambda functor wrapped inside <tt>boost::function</tt> may continue to exist longer, creating the possibility of dangling references.
For example:
<pre class="programlisting">
int* sum = new int();
*sum = 0;
boost::function&lt;int&amp;, int&gt; counter = unlambda(*sum += _1);
counter(5); // ok, *sum = 5;
delete sum;
counter(3); // error, *sum does not exist anymore
</pre>
</p></div><div class="section"><div class="titlepage"><div><h3 class="title"><a name="id2808050"></a>8.2. Boost Bind</h3></div></div><p>
<span class="emphasis"><i>The Boost Bind</i></span> [<a href="bi01.html#cit:boost::bind" title="[bind]">bind</a>] library has partially overlapping functionality with the BLL.
Basically, the Boost Bind library (BB in the sequel) implements the bind expression part of BLL.
There are, however, some semantical differerences.
</p><p>
The BLL and BB evolved separately, and have different implementations.
This means that the bind expressions from the BB cannot be used within bind expressions, or within other type of lambda expressions, of the BLL.
The same holds for using BLL bind expressions in the BB.
The libraries can coexist, however, as
the names of the BB library are in <tt>boost</tt> namespace, whereas the BLL names are in <tt>boost::lambda</tt> namespace.
</p><p>
The BLL requires a compiler that is reasonably conformant to the C++ standard, whereas the BB library is more portable, and works witha a larger set of compilers.
</p><p>
The following two sections describe what are the semantic differences between the bind expressions in BB and BLL.
</p><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2808116"></a>8.2.1. First argument of bind expression</h4></div></div>
In BB the first argument of the bind expression, the target function, is treated differently from the other arguments,
as no argument substitution takes place within that argument.
In BLL the first argument is not a special case in this respect.
For example:
<pre class="programlisting">
template&lt;class F&gt;
int foo(const F&amp; f) {
int x;
..
bind(f, _1)(x);
...
}
</pre><pre class="programlisting">
int bar(int, int);
nested(bind(bar, 1, _1));
</pre>
The bind expression inside <tt>foo</tt> becomes:
<pre class="programlisting">
bind(bind(bar, 1, _1), _1)(x)
</pre>
The BLL interpretes this as:
<pre class="programlisting">
bar(1, x)(x)
</pre>
whereas the BB library as
<pre class="programlisting">
bar(1, x)
</pre>
To get this functionality in BLL, the bind expression inside the <tt>foo</tt> function can be written as:
<pre class="programlisting">
bind(unlambda(f), _1)(x);
</pre>
as explained in <a href="ar01s05.html#sect:unlambda" title="5.9.1.1. Unlambda">Section 5.9.1.1</a>.
</div><div class="section"><div class="titlepage"><div><h4 class="title"><a name="id2808206"></a>8.2.2.
Arity of function objects
</h4></div></div><p>
In both libraries, the highest placeholder index in a bind expression determines the arity of the resulting function object.
However, in the BB library, this is kind of a minimal arity, as the function object can take arbitrarily many arguments; those not needed are discarded.
Consider the two bind expressions and their invocations below:
<pre class="programlisting">
bind(g, _3, _3, _3)(x, y, z);
bind(g, _1, _1, _1)(x, y, z);
</pre>
This first line ends up making the call:
<pre class="programlisting">
g(z, z, z)
</pre>
in both libraries.
The second line is treated differently.
In BLL a compile time error will result, whereas BB will silently ignore the superfluous arguments and invoke:
<pre class="programlisting">
g(x, x, x)
</pre>
In this tradeoff between safety and flexibility, BLL takes the safer route.
Note however, that it is easy to write a lambda functor that would make the above call to
<tt>g(x, x, x)</tt> discarding all but the first argument:
<pre class="programlisting">
(_3, bind(g, _1, _1, _1))(x, y, z);
</pre>
This lambda expression takes three arguments.
The left-hand argument of the comma operator does nothing, and as comma returns the result of evaluating the right-hand argument we end up with the call
<tt>g(x, x, x)</tt>.
</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ar01s07.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s09.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7. Practical considerations </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 9. Contributors</td></tr></table></div></body></html>