Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/functional/mem_fun.html @ 28

Last change on this file since 28 was 12, checked in by landauf, 17 years ago

added boost

File size: 6.3 KB
Line 
1<html>
2
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5<title>Boost Function Object Adapter Library</title>
6</head>
7
8<body bgcolor="#FFFFFF" text="#000000">
9
10<table border="1" bgcolor="#007F7F" cellpadding="2">
11  <tr>
12    <td bgcolor="#FFFFFF"><img src="../../boost.png" alt="boost.png (6897 bytes)" WIDTH="277" HEIGHT="86"></td>
13    <td><a href="../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home </big></font></a></td>
14    <td><a href="../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries </big></font></a></td>
15    <td><a href="../../people/people.htm"><font face="Arial" color="#FFFFFF"><big>People </big></font></a></td>
16    <td><a href="../../more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ </big></font></a></td>
17    <td><a href="../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More </big></font></a></td>
18  </tr>
19</table>
20
21<h1>Member Function Adapters</h1>
22
23<p>The header <nobr><a
24href="../../boost/functional.hpp">functional.hpp</a></nobr> includes
25improved versions of the full range of member function adapters from
26the the C++ Standard Library <nobr>(&sect 20.3.8):</nobr></p>
27
28<ul>
29<li><tt>mem_fun_t</tt></li>
30<li><tt>mem_fun1_t</tt></li>
31<li><tt>const_mem_fun_t</tt></li>
32<li><tt>const_mem_fun1_t</tt></li>
33<li><tt>mem_fun_ref_t</tt></li>
34<li><tt>mem_fun1_ref_t</tt></li>
35<li><tt>const_mem_fun_ref_t</tt></li>
36<li><tt>const_mem_fun1_ref_t</tt></li>
37</ul>
38
39<p>as well as the corresponding overloaded helper functions<p>
40<ul>
41<li><tt>mem_fun</tt></li>
42<li><tt>mem_fun_ref</tt></li>
43</ul>
44
45<p>The following changes have been made to the adapters as specified
46in the Standard:</p>
47
48<ul>
49<li>The <tt><nobr>first_argument_type</nobr></tt> typedef has been
50corrected for the <nobr><tt>const_</tt></nobr> family of member
51function adapters (see <a href="#firstarg">below</a>).</li>
52
53<li>The argument passed to <tt><nobr>mem_fun1_t</nobr></tt> and its
54variants is passed using the
55<tt><nobr>call_traits::param_type</nobr></tt> for the member
56function's argument type.
57</ul>
58
59<h3 id="firstarg">first_argument_type</h3>
60
61<p>The standard specifies <tt><nobr>const_mem_fun1_t</nobr></tt>, for example, like this:
62
63<blockquote><pre>
64template &lt;class S, class T, class A&gt; class const_mem_fun1_t
65  : public binary_function&lt;<strong>T*</strong>, A, S&gt; {
66public:
67  explicit const_mem_fun1_t(S (T::*p)(A) const);
68  S operator()(<strong>const T*</strong> p, A x) const;
69};
70</pre></blockquote>
71
72<p>Note that the first argument to
73<tt><nobr>binary_function</nobr></tt> is <tt><nobr>T*</nobr></tt>
74despite the fact that the first argument to <tt><nobr>operator()</nobr></tt> is
75actually of type <tt><nobr><em>const</em> T*</nobr></tt>
76
77<p>Does this matter?  Well, consider what happens when we write
78
79<blockquote><pre>
80struct Foo { void bar(int) const; };
81const Foo *cp = new Foo;
82std::bind1st(std::mem_fun(&Foo::bar), cp);
83</pre></blockquote>
84
85<p>We have created a <tt><nobr>const_mem_fun1_t</nobr></tt> object
86which will effectively contain the following
87
88<blockquote><pre>
89typedef Foo* first_argument_type;
90</pre></blockquote>
91
92<p>The <tt><nobr>bind1st</nobr></tt> will then create a
93<tt><nobr>binder1st</nobr></tt> object that will use this
94<tt><nobr>typedef</nobr></tt> as the type of a member which will be
95initialised with <tt><nobr>cp</nobr></tt>.  In other words, we will
96need to initialise a <tt><nobr>Foo*</nobr></tt> member with a
97<tt><nobr>const Foo*</nobr></tt> pointer!  Clearly this is not
98possible, so to implement this your Standard Library vendor will have
99had to cast away the constness of <tt><nobr>cp</nobr></tt>, probably
100within the body of <tt><nobr>bind1st</nobr></tt>.
101
102<p>This hack will not suffice with the improved <a
103href="binders.html">binders</a> in this library, so we have had to
104provide corrected versions of the member function adapters as well.
105
106
107<h3 id="args">Argument Types</h3>
108
109<p>The standard defines <nobr><tt>mem_fun1_t</tt></nobr>, for example, like this
110<nobr>(&sect;20.3.8 &para;2):</nobr>
111
112<blockquote><pre>
113template &lt;class S, class T, class A&gt; class mem_fun1_t
114  : public binary_function&lt;T*, A, S&gt; {
115public:
116  explicit mem_fun1_t(S (T::*p)(<strong>A</strong>));
117  S operator()(T* p, <strong>A</strong> x) const;
118};
119</pre></blockquote>
120
121<p>Note that the second argument to <nobr><tt>operator()</tt></nobr> is
122exactly the same type as the argument to the member function.  If this
123is a value type, the argument will be passed by value and copied twice.
124
125<p>However, if we were to try and eliminate this inefficiency by
126instead declaring the argument as <nobr><tt>const A&</tt></nobr>, then
127if A were a reference type, we would have a reference to a reference,
128which is currently illegal (but see <a
129href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#106">C++
130core language issue number 106)</a>
131
132<p>So the way in which we want to declare the second argument for
133<nobr><tt>operator()</tt></nobr> depends on whether or not the member
134function's argument is a reference.  If it is a reference, we want to
135declare it simply as <nobr><tt>A</tt></nobr>; if it is a value we want
136to declare it as <nobr><tt>const A&</tt></nobr>.
137
138<p>The Boost <nobr><a
139href="../utility/call_traits.htm">call_traits</a></nobr> class
140template contains a <tt><nobr>param_type</nobr></tt> typedef, which
141uses partial specialisation to make precisely this decision.  By
142declaring the <nobr><tt>operator()</tt></nobr> as
143
144<blockquote><pre>
145S operator()(T* p, typename call_traits&lt;A&gt;::param_type x) const
146</pre></blockquote>
147
148<p>we achieve the desired result - we improve efficiency without
149generating references to references.</p>
150
151<h3>Limitations</h3>
152
153<p>The call traits template used to realise some improvements relies
154on partial specialisation, so these improvements are only available on
155compilers that support that feature.  With other compilers, the
156argument passed to the member function (in the
157<nobr><tt>mem_fun1_t</tt></nobr> family) will always be passed by
158reference, thus generating the possibility of references to references.
159
160<hr>
161
162<p>Copyright &copy; 2000 Cadenza New Zealand Ltd.  Permission to copy,
163use, modify, sell and distribute this document is granted provided
164this copyright notice appears in all copies. This document is provided
165"as is" without express or implied warranty, and with no claim as to
166its suitability for any purpose.</p>
167
168<p>Revised 28 June 2000</p>
169
170</body>
171</html>
Note: See TracBrowser for help on using the repository browser.