1
0
forked from boostorg/bind
[SVN r43321]
This commit is contained in:
Peter Dimov
2008-02-19 15:09:10 +00:00
parent ef993c777a
commit aef08dd0cd

View File

@@ -307,21 +307,22 @@ std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));
<h3><a name="operators">Overloaded operators</a> (new in Boost 1.33)</h3> <h3><a name="operators">Overloaded operators</a> (new in Boost 1.33)</h3>
<p>For convenience, the function objects produced by <tt>bind</tt> overload the <p>For convenience, the function objects produced by <tt>bind</tt> overload the
logical not operator <code>!</code> and the relational and logical operators <code>==</code>, logical not operator <code>!</code> and the relational and logical operators <code>==</code>,
<code>!=</code>, <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, <code>!=</code>, <code>&lt;</code>, <code>&lt;=</code>, <code>&gt;</code>, <code>&gt;=</code>,
<code>&gt;=</code>, <code>&amp;&amp;</code>, <code>||</code>.</p> <code>&amp;&amp;</code>, <code>||</code>.</p>
<P><tt>!bind(f, ...)</tt> is equivalent to <tt>bind( <EM>logical_not</EM>(), bind(f, <P><tt>!bind(f, ...)</tt> is equivalent to <tt>bind( <EM>logical_not</EM>(), bind(f,
...) )</tt>, where <tt><EM>logical_not</EM></tt> is a function object that ...) )</tt>, where <tt><EM>logical_not</EM></tt> is a function object that
takes one argument <tt>x</tt> and returns <tt>!x</tt>.</P> takes one argument <tt>x</tt> and returns <tt>!x</tt>.</P>
<P><tt>bind(f, ...) <EM>op</EM> x</tt>, where <EM>op</EM> is a relational or logical operator, <P><tt>bind(f, ...) <EM>op</EM> x</tt>, where <EM>op</EM> is a relational or
is equivalent to <tt>bind( <EM>relation</EM>(), bind(f, ...), x )</tt>, where <em>relation</em> logical operator, is equivalent to <tt>bind( <EM>relation</EM>(), bind(f, ...), x )</tt>,
is a function object that takes two arguments <tt>a</tt> and <tt>b</tt> and where <em>relation</em> is a function object that takes two arguments <tt>a</tt>
returns <tt>a <EM>op</EM> b</tt>.</P> and <tt>b</tt> and returns <tt>a <EM>op</EM> b</tt>.</P>
<P>What this means in practice is that you can conveniently negate the result of <tt>bind</tt>:</P> <P>What this means in practice is that you can conveniently negate the result of <tt>bind</tt>:</P>
<P><tt>std::remove_if( first, last, !bind( &amp;X::visible, _1 ) ); // remove invisible <P><tt>std::remove_if( first, last, !bind( &amp;X::visible, _1 ) ); // remove invisible
objects</tt></P> objects</tt></P>
<P>and compare the result of <tt>bind</tt> against a value:</P> <P>and compare the result of <tt>bind</tt> against a value:</P>
<P><tt>std::find_if( first, last, bind( &amp;X::name, _1 ) == "Peter" );</tt></P> <P><tt>std::find_if( first, last, bind( &amp;X::name, _1 ) == "Peter" );</tt></P>
<P><tt>std::find_if( first, last, bind( &amp;X::name, _1 ) == "Peter" || bind( &amp;X::name, _1 ) == "Paul" );</tt></P> <P><tt>std::find_if( first, last, bind( &amp;X::name, _1 ) == "Peter" || bind(
&amp;X::name, _1 ) == "Paul" );</tt></P>
<P>against a placeholder:</P> <P>against a placeholder:</P>
<P><tt>bind( &amp;X::name, _1 ) == _2</tt></P> <P><tt>bind( &amp;X::name, _1 ) == _2</tt></P>
<P>or against another <tt>bind</tt> expression:</P> <P>or against another <tt>bind</tt> expression:</P>
@@ -384,10 +385,12 @@ void connect()
} }
</pre> </pre>
<h2><a name="Limitations">Limitations</a></h2> <h2><a name="Limitations">Limitations</a></h2>
<p>The function objects generated by <b>bind</b> take their arguments by reference <p>As a general rule, the function objects generated by <b>bind</b> take their
and cannot, therefore, accept non-const temporaries or literal constants. This arguments by reference and cannot, therefore, accept non-const temporaries or
is an inherent limitation of the C++ language, known as <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm"> literal constants. This is an inherent limitation of the C++ language in its
the forwarding problem</A>.</p> current (2003) incarnation, known as <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm">
the forwarding problem</A>. (It will be fixed in the next standard, usually
called C++0x.)</p>
<p>The library uses signatures of the form <p>The library uses signatures of the form
</p> </p>
<pre>template&lt;class T&gt; void f(T &amp; t); <pre>template&lt;class T&gt; void f(T &amp; t);
@@ -395,17 +398,17 @@ void connect()
<p>to accept arguments of arbitrary types and pass them on unmodified. As noted, <p>to accept arguments of arbitrary types and pass them on unmodified. As noted,
this does not work with non-const r-values. this does not work with non-const r-values.
</p> </p>
<p>An oft-proposed "solution" to this problem is to add an overload: <p>On compilers that support partial ordering of function templates, a possible
solution is to add an overload:
</p> </p>
<pre>template&lt;class T&gt; void f(T &amp; t); <pre>template&lt;class T&gt; void f(T &amp; t);
template&lt;class T&gt; void f(T const &amp; t); template&lt;class T&gt; void f(T const &amp; t);
</pre> </pre>
<p>Unfortunately, this (a) requires providing 512 overloads for nine arguments and <p>Unfortunately, this requires providing 512 overloads for nine arguments, which
(b) does not actually work for const arguments, both l- and r-values, since the is impractical. The library chooses a small subset: for up to two arguments, it
two templates produce the exact same signature and cannot be partially ordered. provides the const overloads in full, for arities of three and more it provides
</p> a single additional overload with all of the arguments taken by const
<p>[Note: this is a dark corner of the language, and the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#214"> reference. This covers a reasonable portion of the use cases.
corresponding issue</a> has only recently been resolved.]
</p> </p>
<h2><a name="FAQ">Frequently Asked Questions</a></h2> <h2><a name="FAQ">Frequently Asked Questions</a></h2>
<h3><a name="Q_doesnt_compile">Why doesn't this compile?</a></h3> <h3><a name="Q_doesnt_compile">Why doesn't this compile?</a></h3>