blob: 23dc1023e33c16c58b0a3ba393fc1450c9b75b84 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2
3<html>
4<head>
5 <meta http-equiv="Content-Language" content="en-us">
6 <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
7
8 <title>Boost Function Object Adapter Library</title>
9</head>
10
11<body bgcolor="#FFFFFF" text="#000000">
12 <table border="1" bgcolor="#007F7F" cellpadding="2" summary="">
13 <tr>
14 <td bgcolor="#FFFFFF"><img src="../../boost.png" alt=
15 "boost.png (6897 bytes)" width="277" height="86"></td>
16
17 <td><a href="../../index.htm"><font face="Arial" color=
18 "#FFFFFF"><big>Home</big></font></a></td>
19
20 <td><a href="../libraries.htm"><font face="Arial" color=
21 "#FFFFFF"><big>Libraries</big></font></a></td>
22
23 <td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color=
24 "#FFFFFF"><big>People</big></font></a></td>
25
26 <td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color=
27 "#FFFFFF"><big>FAQ</big></font></a></td>
28
29 <td><a href="../../more/index.htm"><font face="Arial" color=
30 "#FFFFFF"><big>More</big></font></a></td>
31 </tr>
32 </table>
33
34 <h1>Member Function Adapters</h1>
35
36 <p>The header <a href="../../boost/functional.hpp">functional.hpp</a>
37 includes improved versions of the full range of member function adapters
38 from the the C++ Standard Library (&sect;20.3.8):</p>
39
40 <ul>
41 <li><tt>mem_fun_t</tt></li>
42
43 <li><tt>mem_fun1_t</tt></li>
44
45 <li><tt>const_mem_fun_t</tt></li>
46
47 <li><tt>const_mem_fun1_t</tt></li>
48
49 <li><tt>mem_fun_ref_t</tt></li>
50
51 <li><tt>mem_fun1_ref_t</tt></li>
52
53 <li><tt>const_mem_fun_ref_t</tt></li>
54
55 <li><tt>const_mem_fun1_ref_t</tt></li>
56 </ul>
57
58 <p>as well as the corresponding overloaded helper functions</p>
59
60 <ul>
61 <li><tt>mem_fun</tt></li>
62
63 <li><tt>mem_fun_ref</tt></li>
64 </ul>
65
66 <p>The following changes have been made to the adapters as specified in the
67 Standard:</p>
68
69 <ul>
70 <li>The <tt>first_argument_type</tt> typedef has been corrected for the
71 <tt>const_</tt> family of member function adapters (see <a href=
72 "#firstarg">below</a>).</li>
73
74 <li>The argument passed to <tt>mem_fun1_t</tt> and its variants is passed
75 using the <tt>call_traits::param_type</tt> for the member function's
76 argument type.</li>
77 </ul>
78
79 <h3 id="firstarg">first_argument_type</h3>
80
81 <p>The standard specifies <tt>const_mem_fun1_t</tt>, for example, like
82 this:</p>
83
84 <blockquote>
85 <pre>
86template &lt;class S, class T, class A&gt; class const_mem_fun1_t
87 : public binary_function&lt;<strong>T*</strong>, A, S&gt; {
88public:
89 explicit const_mem_fun1_t(S (T::*p)(A) const);
90 S operator()(<strong>const T*</strong> p, A x) const;
91};
92</pre>
93 </blockquote>
94
95 <p>Note that the first argument to <tt>binary_function</tt> is <tt>T*</tt>
96 despite the fact that the first argument to <tt>operator()</tt> is actually
97 of type <tt><em>const</em>&nbsp;T*</tt>.</p>
98
99 <p>Does this matter? Well, consider what happens when we write</p>
100
101 <blockquote>
102 <pre>
103struct Foo { void bar(int) const; };
104const Foo *cp = new Foo;
105std::bind1st(std::mem_fun(&amp;Foo::bar), cp);
106</pre>
107 </blockquote>
108
109 <p>We have created a <tt>const_mem_fun1_t</tt> object which will
110 effectively contain the following</p>
111
112 <blockquote>
113 <pre>
114typedef Foo* first_argument_type;
115</pre>
116 </blockquote>
117
118 <p>The <tt>bind1st</tt> will then create a <tt>binder1st</tt> object that
119 will use this <tt>typedef</tt> as the type of a member which will be
120 initialised with <tt>cp</tt>. In other words, we will need to initialise a
121 <tt>Foo*</tt> member with a <tt>const&nbsp;Foo*</tt> pointer! Clearly this
122 is not possible, so to implement this your Standard Library vendor will
123 have had to cast away the constness of <tt>cp</tt>, probably within the
124 body of <tt>bind1st</tt>.</p>
125
126 <p>This hack will not suffice with the improved <a href=
127 "binders.html">binders</a> in this library, so we have had to provide
128 corrected versions of the member function adapters as well.</p>
129
130 <h3 id="args">Argument Types</h3>
131
132 <p>The standard defines <tt>mem_fun1_t</tt>, for example, like this
133 (&sect;20.3.8&nbsp;&para;2):</p>
134
135 <blockquote>
136 <pre>
137template &lt;class S, class T, class A&gt; class mem_fun1_t
138 : public binary_function&lt;T*, A, S&gt; {
139public:
140 explicit mem_fun1_t(S (T::*p)(<strong>A</strong>));
141 S operator()(T* p, <strong>A</strong> x) const;
142};
143</pre>
144 </blockquote>
145
146 <p>Note that the second argument to <tt>operator()</tt> is exactly the same
147 type as the argument to the member function. If this is a value type, the
148 argument will be passed by value and copied twice.</p>
149
150 <p>However, if we were to try and eliminate this inefficiency by instead
151 declaring the argument as <tt>const&nbsp;A&amp;</tt>, then if A were a
152 reference type, we would have a reference to a reference, which is
153 currently illegal (but see <a href=
154 "http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#106">C++ core
155 language issue number 106)</a></p>
156
157 <p>So the way in which we want to declare the second argument for
158 <tt>operator()</tt> depends on whether or not the member function's
159 argument is a reference. If it is a reference, we want to declare it simply
160 as <tt>A</tt>; if it is a value we want to declare it as
161 <tt>const&nbsp;A&amp;</tt>.</p>
162
163 <p>The Boost <a href="../utility/call_traits.htm">call_traits</a> class
164 template contains a <tt>param_type</tt> typedef, which uses partial
165 specialisation to make precisely this decision. By declaring the
166 <tt>operator()</tt> as</p>
167
168 <blockquote>
169 <pre>
170S operator()(T* p, typename call_traits&lt;A&gt;::param_type x) const
171</pre>
172 </blockquote>
173
174 <p>we achieve the desired result - we improve efficiency without generating
175 references to references.</p>
176
177 <h3>Limitations</h3>
178
179 <p>The call traits template used to realise some improvements relies on
180 partial specialisation, so these improvements are only available on
181 compilers that support that feature. With other compilers, the argument
182 passed to the member function (in the <tt>mem_fun1_t</tt> family) will
183 always be passed by reference, thus generating the possibility of
184 references to references.</p>
185 <hr>
186
187 <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
188 "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
189 height="31" width="88"></a></p>
190
191 <p>Revised
192 <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->02 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
193
194 <p><i>Copyright &copy; 2000 Cadenza New Zealand Ltd.</i></p>
195
196 <p><i>Distributed under the Boost Software License, Version 1.0. (See
197 accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
198 copy at <a href=
199 "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
200</body>
201</html>