Documented new feature in tutorial: automatic adaptation of pointers to member functions

Updated reference documentation:
  - Adaptation of pointers to member functions
  - No longer lie about safe_bool
  - Added documentation for operator!
  - Defined "compatible"


[SVN r11458]
This commit is contained in:
Douglas Gregor
2001-10-28 04:52:37 +00:00
parent 6bdc663932
commit e5ff80fb52
2 changed files with 71 additions and 12 deletions

View File

@ -15,8 +15,10 @@
<b>namespace</b> boost { <b>namespace</b> boost {
<b>class</b> <a href="#function_base">function_base</a> <b>class</b> <a href="#function_base">function_base</a>
{ {
<b>typedef</b> <em>implementation-defined</em> safe_bool;
<a href="#empty"><b>bool</b> empty() <b>const</b></a>; <a href="#empty"><b>bool</b> empty() <b>const</b></a>;
<a href="#bool"><b>operator</b> <b>bool</b>() <b>const</b></a>; <a href="#bool"><b>operator</b> safe_bool() <b>const</b></a>;
<a href="#not">safe_bool <b>operator!</b>() <b>const</b></a>;
}; };
// For <i>N</i> in [0, <i>MAX_ARGS</i>] // For <i>N</i> in [0, <i>MAX_ARGS</i>]
@ -65,8 +67,8 @@
<b>typename</b> Policy, <b>typename</b> Policy,
<b>typename</b> Mixin, <b>typename</b> Mixin,
<b>typename</b> Allocator&gt; <b>typename</b> Allocator&gt;
<b>void</b> <a href="#swap_functionN">swap</a>(<b>const</b> function&lt;Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator&gt;<b>&amp;</b>, <b>void</b> <a href="#swap_functionN">swap</a>(<b>const</b> function<em>N</em>&lt;Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator&gt;<b>&amp;</b>,
<b>const</b> function&lt;Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator&gt;<b>&amp;</b>); <b>const</b> function<em>N</em>&lt;Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator&gt;<b>&amp;</b>);
// For any <i>N</i> in [0, <i>MAX_ARGS</i>] // For any <i>N</i> in [0, <i>MAX_ARGS</i>]
<b>template</b>&lt;<b>typename</b> ResultType, <b>template</b>&lt;<b>typename</b> ResultType,
@ -105,6 +107,43 @@
} }
</pre> </pre>
<h2>Definitions</h2>
<p>
<ul>
<li><a name="compatible"></a>A function object <code>f</code> is <em>compatible</em> if for the given set of argument types <code>Arg1</code>, <code>Arg2</code>, ..., <code>Arg<em>N</em></code> and a return type <code>ResultType</code>, the appropriate following function is well-formed:
<pre>
<em>// if ResultType is not <b>void</b></em>
ResultType foo(Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>)
{
<b>return</b> f(arg1, arg2, ..., arg<em>N</em>);
}
<em>// if ResultType is <b>void</b></em>
ResultType foo(Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>)
{
f(arg1, arg2, ..., arg<em>N</em>);
}
</pre>
<p> A special provision is made for pointers to member functions. Though they are not function objects, Boost.Function will adapt them internally to function objects. This requires that a pointer to member function of the form <code>R (X::*mf)(Arg1, Arg2, ..., Arg<em>N</em>) <em>cv-quals</em></code> be adapted to a function object with the following function call operator overloads:
<pre>
R <b>operator</b>()(<em>cv-quals</em> X&amp; x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
{
<b>return</b> x.*mf(arg1, arg2, ..., arg<em>N</em>);
}
R <b>operator</b>()(<em>cv-quals</em> X* x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
{
<b>return</b> x->*mf(arg1, arg2, ..., arg<em>N</em>);
}
<b>template</b>&lt;<b>typename P</b>&gt;
R <b>operator</b>()(<em>cv-quals</em> P&amp; x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
{
<b>return</b> (*x).*mf(arg1, arg2, ..., arg<em>N</em>);
}
</pre>
</ul>
<h2><a name="function_base">Class <code>function_base</code></a></h2> <h2><a name="function_base">Class <code>function_base</code></a></h2>
<p> Class <code>function_base</code> is the common base class for all Boost.Function objects. Objects of type <code>function_base</code> may not be created directly. <p> Class <code>function_base</code> is the common base class for all Boost.Function objects. Objects of type <code>function_base</code> may not be created directly.
@ -114,10 +153,18 @@
<li><b>Throws</b>: will not throw.</li> <li><b>Throws</b>: will not throw.</li>
</ul> </ul>
<p> <a name="bool"><code><b>operator</b> <b>bool</b>() <b>const</b></code></a> <p> <a name="bool"><code><b>operator</b> safe_bool() <b>const</b></code></a>
<ul> <ul>
<li><b>Returns</b>: <code>!<a href="#empty">empty</a>()</code></li> <li><b>Returns</b>: <code>safe_bool</code> equivalent of <code>!<a href="#empty">empty</a>()</code></li>
<li><b>Throws</b>: will not throw.</li> <li><b>Throws</b>: will not throw.</li>
<li><b>Notes</b>: The <code>safe_bool</code> type can be used in contexts where a <b>bool</b> is expected (e.g., an <b>if</b> condition); however, implicit conversions (e.g., to <b>int</b>) that can occur with <b>bool</b> are not allowed, eliminating some sources of user error.
</ul>
<p> <a name="not"><code>safe_bool <b>operator!</b>() <b>const</b></code></a>
<ul>
<li><b>Returns</b>: <code>safe_bool</code> equivalent of <code><a href="#empty">empty</a>()</code></li>
<li><b>Throws</b>: will not throw.</li>
<li><b>Notes</b>: See <a href="#bool"><code>safe_bool</code> conversion</a>
</ul> </ul>
<h2><a name="functionN">Class template <code>function<i>N</i></code></a></h2> <h2><a name="functionN">Class template <code>function<i>N</i></code></a></h2>
@ -137,7 +184,7 @@
<p> <a name="functionN_target"><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i>(<b>const</b> F<b>&amp;</b> g, <b>const</b> Mixin<b>&amp;</b> = Mixin());</code></a> <p> <a name="functionN_target"><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i>(<b>const</b> F<b>&amp;</b> g, <b>const</b> Mixin<b>&amp;</b> = Mixin());</code></a>
<ul> <ul>
<li><b>Requires</b>: <code>g</code> is a compatible function object.</li> <li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li> <li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li>
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li> <li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
<li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li> <li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li>
@ -151,7 +198,7 @@
<p> <a name="functionN_target_assn"><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i><b>&amp;</b> <b>operator</b>=(<b>const</b> F<b>&amp;</b> g);</code></a> <p> <a name="functionN_target_assn"><code><b>template</b>&lt;<b>typename</b> F&gt; function<i>N</i><b>&amp;</b> <b>operator</b>=(<b>const</b> F<b>&amp;</b> g);</code></a>
<ul> <ul>
<li><b>Requires</b>: <code>g</code> is a compatible function object.</li> <li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li> <li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
<li><b>Returns</b>: <code>*this</code>.</li> <li><b>Returns</b>: <code>*this</code>.</li>
<li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li> <li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li>
@ -233,7 +280,7 @@
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address> <address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
<!-- Created: Fri Jul 13 10:57:20 EDT 2001 --> <!-- Created: Fri Jul 13 10:57:20 EDT 2001 -->
<!-- hhmts start --> <!-- hhmts start -->
Last modified: Sun Jul 22 01:29:50 EDT 2001 Last modified: Sun Oct 28 00:40:55 EDT 2001
<!-- hhmts end --> <!-- hhmts end -->
</body> </body>
</html> </html>

View File

@ -66,8 +66,22 @@ else
<h3>Member functions</h3> <h3>Member functions</h3>
<a name="member_func"> <a name="member_func">
<p> In many systems, callbacks often call to member functions of a particular <p> In many systems, callbacks often call to member functions of a particular
object. Handling argument binding is beyond the scope of Boost.Function. However, there are several libraries that perform 'argument binding', including object. This is often referred to as "argument binding", and is beyond the scope of Boost.Function. The use of member functions directly, however, is supported, so the following code is valid:
<pre>
struct X {
int foo(int);
};
boost::function&lt;int, X*, int&gt; f;
f = &X::foo;
X x;
f(&x, 5);
</pre>
<p> Several libraries exist that support argument binding. Three such libraries are summarized below:
<ul> <ul>
<li> <a href="../../bind/bind.html">Boost.Bind</a>. This library allows binding of arguments for any function object. It is lightweight and very portable.</li>
<li> The C++ Standard library. Using <code>std::bind1st</code> and <code>std::mem_fun</code> together one can bind the object of a pointer-to-member function for use with Boost.Function: <li> The C++ Standard library. Using <code>std::bind1st</code> and <code>std::mem_fun</code> together one can bind the object of a pointer-to-member function for use with Boost.Function:
<pre> <pre>
struct X { struct X {
@ -81,8 +95,6 @@ object. Handling argument binding is beyond the scope of Boost.Function. However
f(5); // Call x.foo(5)</pre></li> f(5); // Call x.foo(5)</pre></li>
<li><a href="http://lambda.cs.utu.fi/">The Lambda library</a>. This library provides a powerful composition mechanism to construct function objects that uses very natural C++ syntax. Lambda requires a compiler that is reasonably conformant to the C++ standard. Note that it is not a Boost library.</li> <li><a href="http://lambda.cs.utu.fi/">The Lambda library</a>. This library provides a powerful composition mechanism to construct function objects that uses very natural C++ syntax. Lambda requires a compiler that is reasonably conformant to the C++ standard. Note that it is not a Boost library.</li>
<li>Peter Dimov's <a href="http://groups.yahoo.com/group/boost/files/bind/bind.hpp">bind</a> library. It has a smaller scope than the Lambda Library but is more tolerant of broken compilers. It is an unreviewed library in development.</li>
</ul> </ul>
<h2><a name="family">The <code>function</code> family</a></h2> <h2><a name="family">The <code>function</code> family</a></h2>
@ -161,7 +173,7 @@ boost::function2&lt;float, int, int, SynchronizedPolicy, SynchronizedMixin&gt; f
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address> <address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
<!-- Created: Fri Jul 13 12:47:11 EDT 2001 --> <!-- Created: Fri Jul 13 12:47:11 EDT 2001 -->
<!-- hhmts start --> <!-- hhmts start -->
Last modified: Fri Jul 13 23:58:17 EDT 2001 Last modified: Sun Oct 28 00:49:02 EDT 2001
<!-- hhmts end --> <!-- hhmts end -->
</body> </body>
</html> </html>