1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
---|
2 | <html> |
---|
3 | <head> |
---|
4 | <title>Boost: bind.hpp documentation</title> |
---|
5 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
---|
6 | </head> |
---|
7 | <body style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%" bgColor="white"> |
---|
8 | <table width="100%" border="0"> |
---|
9 | <tr> |
---|
10 | <td width="277"><A href="../../index.htm"><IMG height="86" alt="boost.png (6897 bytes)" src="../../boost.png" width="277" border="0"></A> |
---|
11 | </td> |
---|
12 | <td align="center"> |
---|
13 | <h1>bind.hpp</h1> |
---|
14 | </td> |
---|
15 | </tr> |
---|
16 | <tr> |
---|
17 | <td colSpan="2" height="64"> </td> |
---|
18 | </tr> |
---|
19 | </table> |
---|
20 | <h2>Contents</h2> |
---|
21 | <h3 style="MARGIN-LEFT: 20pt"><A href="#Purpose">Purpose</A></h3> |
---|
22 | <h4 style="MARGIN-LEFT: 40pt"><A href="#with_functions">Using bind with functions and |
---|
23 | function pointers</A></h4> |
---|
24 | <h4 style="MARGIN-LEFT: 40pt"><A href="#with_function_objects">Using bind with function |
---|
25 | objects</A></h4> |
---|
26 | <h4 style="MARGIN-LEFT: 40pt"><A href="#with_member_pointers">Using bind with pointers |
---|
27 | to members</A></h4> |
---|
28 | <h4 style="MARGIN-LEFT: 40pt"><A href="#nested_binds">Using nested binds for function |
---|
29 | composition</A></h4> |
---|
30 | <h4 style="MARGIN-LEFT: 40pt"><A href="#operators">Overloaded operators</A></h4> |
---|
31 | <h3 style="MARGIN-LEFT: 20pt"><A href="#Examples">Examples</A></h3> |
---|
32 | <h4 style="MARGIN-LEFT: 40pt"><A href="#with_algorithms">Using bind with standard |
---|
33 | algorithms</A></h4> |
---|
34 | <h4 style="MARGIN-LEFT: 40pt"><A href="#with_boost_function">Using bind with |
---|
35 | Boost.Function</A></h4> |
---|
36 | <h3 style="MARGIN-LEFT: 20pt"><A href="#Limitations">Limitations</A></h3> |
---|
37 | <h3 style="MARGIN-LEFT: 20pt"><A href="#FAQ">Frequently Asked Questions</A></h3> |
---|
38 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_doesnt_compile">Why doesn't this compile?</A></h4> |
---|
39 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_does_compile">Why does this compile? It |
---|
40 | should not.</A></h4> |
---|
41 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_forms">What is the difference between bind(f, |
---|
42 | ...) and bind<R>(f, ...)?</A></h4> |
---|
43 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_win32_api">Does <b>bind</b> work with Windows |
---|
44 | API functions?</A></h4> |
---|
45 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_com">Does <b>bind</b> work with COM methods?</A></h4> |
---|
46 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_mac">Does <b>bind</b> work with Mac toolbox |
---|
47 | functions?</A></h4> |
---|
48 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_extern_C">Does <b>bind</b> work with extern |
---|
49 | "C" functions?</A></h4> |
---|
50 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Q_auto_stdcall">Why doesn't <b>bind</b> automatically |
---|
51 | recognize nonstandard functions?</A></h4> |
---|
52 | <h3 style="MARGIN-LEFT: 20pt"><A href="#Troubleshooting">Troubleshooting</A></h3> |
---|
53 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_num_args">Incorrect number of arguments</A></h4> |
---|
54 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_signature">The function object cannot be |
---|
55 | called with the specified arguments</A></h4> |
---|
56 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_arg_access">Accessing an argument that does |
---|
57 | not exist</A></h4> |
---|
58 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_short_form">Inappropriate use of bind(f, |
---|
59 | ...)</A></h4> |
---|
60 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_long_form">Inappropriate use of |
---|
61 | bind<R>(f, ...)</A></h4> |
---|
62 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_nonstd">Binding a nonstandard function</A></h4> |
---|
63 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_const_arg"><b>const</b> in signatures</A></h4> |
---|
64 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_msvc_using">MSVC specific: using |
---|
65 | boost::bind;</A></h4> |
---|
66 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_msvc_class_template">MSVC specific: class |
---|
67 | templates shadow function templates</A></h4> |
---|
68 | <h4 style="MARGIN-LEFT: 40pt"><A href="#err_msvc_ellipsis">MSVC specific: ... in |
---|
69 | signatures treated as type</A></h4> |
---|
70 | <h3 style="MARGIN-LEFT: 20pt"><A href="#Interface">Interface</A></h3> |
---|
71 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Synopsis">Synopsis</A></h4> |
---|
72 | <h4 style="MARGIN-LEFT: 40pt"><A href="#CommonRequirements">Common requirements</A></h4> |
---|
73 | <h4 style="MARGIN-LEFT: 40pt"><A href="#CommonDefinitions">Common definitions</A></h4> |
---|
74 | <h4 style="MARGIN-LEFT: 40pt"><A href="#bind">bind</A></h4> |
---|
75 | <h4 style="MARGIN-LEFT: 40pt"><A href="#AdditionalOverloads">Additional overloads</A></h4> |
---|
76 | <h3 style="MARGIN-LEFT: 20pt"><A href="#Implementation">Implementation</A></h3> |
---|
77 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Files">Files</A></h4> |
---|
78 | <h4 style="MARGIN-LEFT: 40pt"><A href="#Dependencies">Dependencies</A></h4> |
---|
79 | <h4 style="MARGIN-LEFT: 40pt"><A href="#NumberOfArguments">Number of Arguments</A></h4> |
---|
80 | <h4 style="MARGIN-LEFT: 40pt"><A href="#stdcall">"__stdcall", "__cdecl", "__fastcall", |
---|
81 | and "pascal" Support</A></h4> |
---|
82 | <h4 style="MARGIN-LEFT: 40pt"><A href="#visit_each"><b>visit_each</b> support</A></h4> |
---|
83 | <h3 style="MARGIN-LEFT: 20pt"><A href="#Acknowledgements">Acknowledgements</A></h3> |
---|
84 | <h2><a name="Purpose">Purpose</a></h2> |
---|
85 | <p><b>boost::bind</b> is a generalization of the standard functions <b>std::bind1st</b> |
---|
86 | and <b>std::bind2nd</b>. It supports arbitrary function objects, functions, |
---|
87 | function pointers, and member function pointers, and is able to bind any |
---|
88 | argument to a specific value or route input arguments into arbitrary positions. <b>bind</b> |
---|
89 | does not place any requirements on the function object; in particular, it does |
---|
90 | not need the <b>result_type</b>, <b>first_argument_type</b> and <b>second_argument_type</b> |
---|
91 | standard typedefs. |
---|
92 | </p> |
---|
93 | <h3><a name="with_functions">Using bind with functions and function pointers</a></h3> |
---|
94 | <p>Given these definitions: |
---|
95 | </p> |
---|
96 | <pre>int f(int a, int b) |
---|
97 | { |
---|
98 | return a + b; |
---|
99 | } |
---|
100 | |
---|
101 | int g(int a, int b, int c) |
---|
102 | { |
---|
103 | return a + b + c; |
---|
104 | } |
---|
105 | </pre> |
---|
106 | <p><tt>bind(f, 1, 2)</tt> will produce a "nullary" function object that takes no |
---|
107 | arguments and returns <tt>f(1, 2)</tt>. Similarly, <tt>bind(g, 1, 2, 3)()</tt> is |
---|
108 | equivalent to <tt>g(1, 2, 3)</tt>. |
---|
109 | </p> |
---|
110 | <p>It is possible to selectively bind only some of the arguments. <tt>bind(f, _1, 5)(x)</tt> |
---|
111 | is equivalent to <tt>f(x, 5)</tt>; here <b>_1</b> |
---|
112 | is a placeholder argument that means "substitute with the first input |
---|
113 | argument." |
---|
114 | <p>For comparison, here is the same operation expressed with the standard library |
---|
115 | primitives: |
---|
116 | </p> |
---|
117 | <pre>std::bind2nd(std::ptr_fun(f), 5)(x); |
---|
118 | </pre> |
---|
119 | <p><b>bind</b> covers the functionality of <b>std::bind1st</b> as well: |
---|
120 | </p> |
---|
121 | <pre>std::bind1st(std::ptr_fun(f), 5)(x); // f(5, x) |
---|
122 | bind(f, 5, _1)(x); // f(5, x) |
---|
123 | </pre> |
---|
124 | <p><b>bind</b> can handle functions with more than two arguments, and its argument |
---|
125 | substitution mechanism is more general: |
---|
126 | </p> |
---|
127 | <pre>bind(f, _2, _1)(x, y); // f(y, x) |
---|
128 | |
---|
129 | bind(g, _1, 9, _1)(x); // g(x, 9, x) |
---|
130 | |
---|
131 | bind(g, _3, _3, _3)(x, y, z); // g(z, z, z) |
---|
132 | |
---|
133 | bind(g, _1, _1, _1)(x, y, z); // g(x, x, x) |
---|
134 | </pre> |
---|
135 | <p>Note that, in the last example, the function object produced by <tt>bind(g, _1, _1, |
---|
136 | _1)</tt> does not contain references to any arguments beyond the first, but |
---|
137 | it can still be used with more than one argument. Any extra arguments are |
---|
138 | silently ignored, just like the first and the second argument are ignored in |
---|
139 | the third example. |
---|
140 | </p> |
---|
141 | <p>The arguments that <b>bind</b> takes are copied and held internally by the |
---|
142 | returned function object. For example, in the following code: |
---|
143 | </p> |
---|
144 | <pre>int i = 5; |
---|
145 | |
---|
146 | bind(f, i, _1); |
---|
147 | </pre> |
---|
148 | <p>a copy of the value of <b>i</b> is stored into the function object. <A href="ref.html"> |
---|
149 | boost::ref</A> and <A href="ref.html">boost::cref</A> can be used to make |
---|
150 | the function object store a reference to an object, rather than a copy: |
---|
151 | </p> |
---|
152 | <pre>int i = 5; |
---|
153 | |
---|
154 | bind(f, ref(i), _1); |
---|
155 | |
---|
156 | bind(f, cref(42), _1); |
---|
157 | </pre> |
---|
158 | <h3><a name="with_function_objects">Using bind with function objects</a></h3> |
---|
159 | <p><b>bind</b> is not limited to functions; it accepts arbitrary function objects. |
---|
160 | In the general case, the return type of the generated function object's <b>operator()</b> |
---|
161 | has to be specified explicitly (without a <b>typeof</b> operator the return |
---|
162 | type cannot be inferred): |
---|
163 | </p> |
---|
164 | <pre>struct F |
---|
165 | { |
---|
166 | int operator()(int a, int b) { return a - b; } |
---|
167 | bool operator()(long a, long b) { return a == b; } |
---|
168 | }; |
---|
169 | |
---|
170 | F f; |
---|
171 | |
---|
172 | int x = 104; |
---|
173 | |
---|
174 | bind<int>(f, _1, _1)(x); // f(x, x), i.e. zero |
---|
175 | </pre> |
---|
176 | <p>Some compilers have trouble with the <tt>bind<R>(f, ...)</tt> syntax. For |
---|
177 | portability reasons, an alternative way to express the above is supported:</p> |
---|
178 | <pre>boost::bind(boost::type<int>(), f, _1, _1)(x); |
---|
179 | </pre> |
---|
180 | <P>Note, however, that the alternative syntax is provided only as a workaround. It |
---|
181 | is not part of the interface.</P> |
---|
182 | <P>When the function object exposes a nested type named <b>result_type</b>, the |
---|
183 | explicit return type can be omitted: |
---|
184 | </P> |
---|
185 | <pre>int x = 8; |
---|
186 | |
---|
187 | bind(std::less<int>(), _1, 9)(x); // x < 9 |
---|
188 | </pre> |
---|
189 | <p>[Note: the ability to omit the return type is not available on all compilers.] |
---|
190 | </p> |
---|
191 | <h3><a name="with_member_pointers">Using bind with pointers to members</a></h3> |
---|
192 | <p>Pointers to member functions and pointers to data members are not function |
---|
193 | objects, because they do not support <tt>operator()</tt>. For convenience, <b>bind</b> |
---|
194 | accepts member pointers as its first argument, and the behavior is as if <A href="mem_fn.html"> |
---|
195 | boost::mem_fn</A> has been used to convert the member pointer into a |
---|
196 | function object. In other words, the expression |
---|
197 | </p> |
---|
198 | <pre>bind(&X::f, <i>args</i>) |
---|
199 | </pre> |
---|
200 | <p>is equivalent to |
---|
201 | </p> |
---|
202 | <pre>bind<R>(<A href="mem_fn.html" >mem_fn</A>(&X::f), <i>args</i>) |
---|
203 | </pre> |
---|
204 | <p>where <b>R</b> is the return type of <b>X::f</b> (for member functions) or the |
---|
205 | type of the member (for data members.) |
---|
206 | </p> |
---|
207 | <p>[Note: <b>mem_fn</b> creates function objects that are able to accept a pointer, |
---|
208 | a reference, or a smart pointer to an object as its first argument; for |
---|
209 | additional information, see the <b>mem_fn</b> <A href="mem_fn.html">documentation</A>.] |
---|
210 | </p> |
---|
211 | <p>Example: |
---|
212 | </p> |
---|
213 | <pre>struct X |
---|
214 | { |
---|
215 | bool f(int a); |
---|
216 | }; |
---|
217 | |
---|
218 | X x; |
---|
219 | |
---|
220 | shared_ptr<X> p(new X); |
---|
221 | |
---|
222 | int i = 5; |
---|
223 | |
---|
224 | bind(&X::f, ref(x), _1)(i); // x.f(i) |
---|
225 | bind(&X::f, &x, _1)(i); //(&x)->f(i) |
---|
226 | bind(&X::f, x, _1)(i); // (<i>internal copy of x</i>).f(i) |
---|
227 | bind(&X::f, p, _1)(i); // (<i>internal copy of p</i>)->f(i) |
---|
228 | </pre> |
---|
229 | <p>The last two examples are interesting in that they produce "self-contained" |
---|
230 | function objects. <tt>bind(&X::f, x, _1)</tt> stores a copy of <b>x</b>. <tt>bind(&X::f, |
---|
231 | p, _1)</tt> stores a copy of <b>p</b>, and since <b>p</b> is a <A href="../smart_ptr/shared_ptr.htm"> |
---|
232 | boost::shared_ptr</A>, the function object retains a reference to its |
---|
233 | instance of <b>X</b> and will remain valid even when <b>p</b> goes out of scope |
---|
234 | or is <b>reset()</b>. |
---|
235 | </p> |
---|
236 | <h3><a name="nested_binds">Using nested binds for function composition</a></h3> |
---|
237 | <p>Some of the arguments passed to <b>bind</b> may be nested <b>bind</b> expressions |
---|
238 | themselves: |
---|
239 | </p> |
---|
240 | <pre>bind(f, bind(g, _1))(x); // f(g(x)) |
---|
241 | </pre> |
---|
242 | <p>The inner <STRONG>bind</STRONG> expressions are evaluated, in unspecified order, |
---|
243 | before the outer <STRONG>bind</STRONG> when the function object is called; the |
---|
244 | results of the evaluation are then substituted in their place when the outer <STRONG> |
---|
245 | bind</STRONG> is evaluated. In the example above, when the function object |
---|
246 | is called with the argument list <tt>(x)</tt>, <tt>bind(g, _1)(x)</tt> is |
---|
247 | evaluated first, yielding <tt>g(x)</tt>, and then <tt>bind(f, g(x))(x)</tt> is |
---|
248 | evaluated, yielding the final result <tt>f(g(x))</tt>. |
---|
249 | </p> |
---|
250 | <P>This feature of <b>bind</b> can be used to perform function composition. See <A href="bind_as_compose.cpp"> |
---|
251 | bind_as_compose.cpp</A> for an example that demonstrates how to use <b>bind</b> |
---|
252 | to achieve similar functionality to <A href="../compose/index.htm">Boost.Compose</A>. |
---|
253 | </P> |
---|
254 | <p>Note that the first argument - the bound function object - is not evaluated, |
---|
255 | even when it's a function object that is produced by <STRONG>bind</STRONG> or a |
---|
256 | placeholder argument, so the example below does not work as expected: |
---|
257 | </p> |
---|
258 | <pre>typedef void (*pf)(int); |
---|
259 | |
---|
260 | std::vector<pf> v; |
---|
261 | |
---|
262 | std::for_each(v.begin(), v.end(), bind(_1, 5)); |
---|
263 | </pre> |
---|
264 | <p>The desired effect can be achieved via a helper function object <STRONG>apply</STRONG> |
---|
265 | that applies its first argument, as a function object, to the rest of its |
---|
266 | argument list. For convenience, an implementation of <STRONG>apply</STRONG> is |
---|
267 | provided in the <STRONG>boost/bind/apply.hpp</STRONG> header file. Here is how |
---|
268 | the modified version of the previous example looks like: |
---|
269 | </p> |
---|
270 | <pre>typedef void (*pf)(int); |
---|
271 | |
---|
272 | std::vector<pf> v; |
---|
273 | |
---|
274 | std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5)); |
---|
275 | </pre> |
---|
276 | <P>Although the first argument is, by default, not evaluated, all other arguments |
---|
277 | are. Sometimes it is necessary not to evaluate arguments subsequent to the |
---|
278 | first, even when they are nested <STRONG>bind</STRONG> subexpressions. This can |
---|
279 | be achieved with the help of another function object, <STRONG>protect</STRONG>, |
---|
280 | that masks the type so that <STRONG>bind</STRONG> does not recognize and |
---|
281 | evaluate it. When called, <STRONG>protect</STRONG> simply forwards the argument |
---|
282 | list to the other function object unmodified.</P> |
---|
283 | <P>The header <STRONG>boost/bind/protect.hpp</STRONG> contains an implementation of <STRONG> |
---|
284 | protect</STRONG>. To protect a <STRONG>bind</STRONG> function object from |
---|
285 | evaluation, use <tt>protect(bind(f, ...))</tt>.</P> |
---|
286 | <h3><a name="operators">Overloaded operators</a> (new in Boost 1.33)</h3> |
---|
287 | <p>For convenience, the function objects produced by <tt>bind</tt> overload the |
---|
288 | logical not operator <STRONG>!</STRONG> and the relational operators <STRONG>==</STRONG>, |
---|
289 | <STRONG>!=</STRONG>, <STRONG><</STRONG>, <STRONG><=</STRONG>, <STRONG>></STRONG>, |
---|
290 | <STRONG>>=</STRONG>.</p> |
---|
291 | <P><tt>!bind(f, ...)</tt> is equivalent to <tt>bind( <EM>logical_not</EM>(), bind(f, |
---|
292 | ...) )</tt>, where <tt><EM>logical_not</EM></tt> is a function object that |
---|
293 | takes one argument <tt>x</tt> and returns <tt>!x</tt>.</P> |
---|
294 | <P><tt>bind(f, ...) <EM>op</EM> x</tt>, where <EM>op</EM> is a relational operator, |
---|
295 | is equivalent to <tt>bind( <EM>relation</EM>(), bind(f, ...), x )</tt>, where <em>relation</em> |
---|
296 | is a function object that takes two arguments <tt>a</tt> and <tt>b</tt> and |
---|
297 | returns <tt>a <EM>op</EM> b</tt>.</P> |
---|
298 | <P>What this means in practice is that you can conveniently negate the result of <tt>bind</tt>:</P> |
---|
299 | <P><tt>std::remove_if( first, last, !bind( &X::visible, _1 ) ); // remove invisible |
---|
300 | objects</tt></P> |
---|
301 | <P>and compare the result of <tt>bind</tt> against a value:</P> |
---|
302 | <P><tt>std::find_if( first, last, bind( &X::name, _1 ) == "peter" );</tt></P> |
---|
303 | <P>against a placeholder:</P> |
---|
304 | <P><tt>bind( &X::name, _1 ) == _2</tt></P> |
---|
305 | <P>or against another <tt>bind</tt> expression:</P> |
---|
306 | <P><tt>std::sort( first, last, bind( &X::name, _1 ) < bind( &X::name, _2 ) |
---|
307 | ); // sort by name</tt></P> |
---|
308 | <h2><a name="Examples">Examples</a></h2> |
---|
309 | <h3><a name="with_algorithms">Using bind with standard algorithms</a></h3> |
---|
310 | <pre>class image; |
---|
311 | |
---|
312 | class animation |
---|
313 | { |
---|
314 | public: |
---|
315 | |
---|
316 | void advance(int ms); |
---|
317 | bool inactive() const; |
---|
318 | void render(image & target) const; |
---|
319 | }; |
---|
320 | |
---|
321 | std::vector<animation> anims; |
---|
322 | |
---|
323 | template<class C, class P> void erase_if(C & c, P pred) |
---|
324 | { |
---|
325 | c.erase(std::remove_if(c.begin(), c.end(), pred), c.end()); |
---|
326 | } |
---|
327 | |
---|
328 | void update(int ms) |
---|
329 | { |
---|
330 | std::for_each(anims.begin(), anims.end(), boost::bind(&animation::advance, _1, ms)); |
---|
331 | erase_if(anims, boost::mem_fn(&animation::inactive)); |
---|
332 | } |
---|
333 | |
---|
334 | void render(image & target) |
---|
335 | { |
---|
336 | std::for_each(anims.begin(), anims.end(), boost::bind(&animation::render, _1, boost::ref(target))); |
---|
337 | } |
---|
338 | </pre> |
---|
339 | <h3><a name="with_boost_function">Using bind with Boost.Function</a></h3> |
---|
340 | <pre>class button |
---|
341 | { |
---|
342 | public: |
---|
343 | |
---|
344 | <A href="../function/index.html" >boost::function</A><void> onClick; |
---|
345 | }; |
---|
346 | |
---|
347 | class player |
---|
348 | { |
---|
349 | public: |
---|
350 | |
---|
351 | void play(); |
---|
352 | void stop(); |
---|
353 | }; |
---|
354 | |
---|
355 | button playButton, stopButton; |
---|
356 | player thePlayer; |
---|
357 | |
---|
358 | void connect() |
---|
359 | { |
---|
360 | playButton.onClick = boost::bind(&player::play, &thePlayer); |
---|
361 | stopButton.onClick = boost::bind(&player::stop, &thePlayer); |
---|
362 | } |
---|
363 | </pre> |
---|
364 | <h2><a name="Limitations">Limitations</a></h2> |
---|
365 | <p>The function objects generated by <b>bind</b> take their arguments by reference |
---|
366 | and cannot, therefore, accept non-const temporaries or literal constants. This |
---|
367 | is an inherent limitation of the C++ language, known as <A href="http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm"> |
---|
368 | the forwarding problem</A>.</p> |
---|
369 | <p>The library uses signatures of the form |
---|
370 | </p> |
---|
371 | <pre>template<class T> void f(T & t); |
---|
372 | </pre> |
---|
373 | <p>to accept arguments of arbitrary types and pass them on unmodified. As noted, |
---|
374 | this does not work with non-const r-values. |
---|
375 | </p> |
---|
376 | <p>An oft-proposed "solution" to this problem is to add an overload: |
---|
377 | </p> |
---|
378 | <pre>template<class T> void f(T & t); |
---|
379 | template<class T> void f(T const & t); |
---|
380 | </pre> |
---|
381 | <p>Unfortunately, this (a) requires providing 512 overloads for nine arguments and |
---|
382 | (b) does not actually work for const arguments, both l- and r-values, since the |
---|
383 | two templates produce the exact same signature and cannot be partially ordered. |
---|
384 | </p> |
---|
385 | <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"> |
---|
386 | corresponding issue</a> has only recently been resolved.] |
---|
387 | </p> |
---|
388 | <h2><a name="FAQ">Frequently Asked Questions</a></h2> |
---|
389 | <h3><a name="Q_doesnt_compile">Why doesn't this compile?</a></h3> |
---|
390 | <p>See the <A href="#Troubleshooting">dedicated Troubleshooting section</A>.</p> |
---|
391 | <h3><a name="Q_does_compile">Why does this compile? It should not.</a></h3> |
---|
392 | <p>Probably because you used the general <tt>bind<R>(f, ...)</tt> syntax, |
---|
393 | thereby instructing <b>bind</b> to not "inspect" <b>f</b> to detect arity and |
---|
394 | return type errors.</p> |
---|
395 | <h3><a name="Q_forms">What is the difference between bind(f, ...) and bind<R>(f, |
---|
396 | ...)?</a></h3> |
---|
397 | <p>The first form instructs <b>bind</b> to inspect the type of <b>f</b> in order to |
---|
398 | determine its arity (number of arguments) and return type. Arity errors will be |
---|
399 | detected at "bind time". This syntax, of course, places some requirements on <b>f</b>. |
---|
400 | It must be a function, function pointer, member function pointer, or a function |
---|
401 | object that defines a nested type named <b>result_type</b>; in short, it must |
---|
402 | be something that <b>bind</b> can recognize.</p> |
---|
403 | <p>The second form instructs <b>bind</b> to <b>not</b> attempt to recognize the |
---|
404 | type of <b>f</b>. It is generally used with function objects that do not, or |
---|
405 | cannot, expose <b>result_type</b>, but it can also be used with nonstandard |
---|
406 | functions. For example, the current implementation does not automatically |
---|
407 | recognize variable-argument functions like <b>printf</b>, so you will have to |
---|
408 | use <tt>bind<int>(printf, ...)</tt>. Note that an alternative <tt>bind(type<R>(), |
---|
409 | f, ...)</tt> syntax is supported for portability reasons.</p> |
---|
410 | <p>Another important factor to consider is that compilers without partial template |
---|
411 | specialization or function template partial ordering support cannot handle the |
---|
412 | first form when <b>f</b> is a function object, and in most cases will not |
---|
413 | handle the second form when <b>f</b> is a function (pointer) or a member |
---|
414 | function pointer.</p> |
---|
415 | <h3><a name="Q_win32_api">Does <b>bind</b> work with Windows API functions?</a></h3> |
---|
416 | <p>Yes, if you <A href="#stdcall">#define BOOST_BIND_ENABLE_STDCALL</A>. An |
---|
417 | alternative is to treat the function as a <A href="#with_function_objects">generic |
---|
418 | function object</A> and use the <tt>bind<R>(f, ...)</tt> syntax.</p> |
---|
419 | <h3><a name="Q_com">Does <b>bind</b> work with COM methods?</a></h3> |
---|
420 | <p>Yes, if you <A href="#stdcall">#define BOOST_MEM_FN_ENABLE_STDCALL</A>.</p> |
---|
421 | <h3><a name="Q_mac">Does <b>bind</b> work with Mac toolbox functions?</a></h3> |
---|
422 | <p>Yes, if you <A href="#stdcall">#define BOOST_BIND_ENABLE_PASCAL</A>. An |
---|
423 | alternative is to treat the function as a <A href="#with_function_objects">generic |
---|
424 | function object</A> and use the <tt>bind<R>(f, ...)</tt> syntax.</p> |
---|
425 | <h3><a name="Q_extern_C">Does <b>bind</b> work with extern "C" functions?</a></h3> |
---|
426 | <p>Sometimes. On some platforms, pointers to extern "C" functions are equivalent to |
---|
427 | "ordinary" function pointers, so they work fine. Other platforms treat them as |
---|
428 | different types. A platform-specific implementation of <b>bind</b> is expected |
---|
429 | to handle the problem transparently; this implementation does not. As usual, |
---|
430 | the workaround is to treat the function as a <A href="#with_function_objects">generic |
---|
431 | function object</A> and use the <tt>bind<R>(f, ...)</tt> syntax.</p> |
---|
432 | <h3><a name="Q_auto_stdcall">Why doesn't <b>bind</b> automatically recognize |
---|
433 | nonstandard functions?</a></h3> |
---|
434 | <p>Non-portable extensions, in general, should default to off to prevent vendor |
---|
435 | lock-in. Had the <A href="#stdcall">appropriate macros</A> been defined |
---|
436 | automatically, you could have accidentally taken advantage of them without |
---|
437 | realizing that your code is, perhaps, no longer portable. In addition, some |
---|
438 | compilers have the option to make <b>__stdcall</b> (<STRONG>__fastcall</STRONG>) |
---|
439 | their default calling convention, in which case no separate support would be |
---|
440 | necessary.</p> |
---|
441 | <h2><a name="Troubleshooting">Troubleshooting</a></h2> |
---|
442 | <h3><a name="err_num_args">Incorrect number of arguments</a></h3> |
---|
443 | <p>In a <tt>bind(f, a1, a2, ..., aN)</tt> expression, the function object <b>f</b> must |
---|
444 | be able to take exactly <b>N</b> arguments. This error is normally detected at |
---|
445 | "bind time"; in other words, the compilation error is reported on the line |
---|
446 | where bind() is invoked:</p> |
---|
447 | <pre>int f(int, int); |
---|
448 | |
---|
449 | int main() |
---|
450 | { |
---|
451 | boost::bind(f, 1); // error, f takes two arguments |
---|
452 | boost::bind(f, 1, 2); // OK |
---|
453 | } |
---|
454 | </pre> |
---|
455 | <p>A common variation of this error is to forget that member functions have an |
---|
456 | implicit "this" argument:</p> |
---|
457 | <pre>struct X |
---|
458 | { |
---|
459 | int f(int); |
---|
460 | } |
---|
461 | |
---|
462 | int main() |
---|
463 | { |
---|
464 | boost::bind(&X::f, 1); // error, X::f takes two arguments |
---|
465 | boost::bind(&X::f, <b>_1</b>, 1); // OK |
---|
466 | } |
---|
467 | </pre> |
---|
468 | <h3><a name="err_signature">The function object cannot be called with the specified |
---|
469 | arguments</a></h3> |
---|
470 | <p>As in normal function calls, the function object that is bound must be |
---|
471 | compatible with the argument list. The incompatibility will usually be detected |
---|
472 | by the compiler at "call time" and the result is typically an error in <b>bind.hpp</b> |
---|
473 | on a line that looks like:</p> |
---|
474 | <pre> return f(a[a1_], a[a2_]); |
---|
475 | </pre> |
---|
476 | <p>An example of this kind of error:</p> |
---|
477 | <pre>int f(int); |
---|
478 | |
---|
479 | int main() |
---|
480 | { |
---|
481 | boost::bind(f, "incompatible"); // OK so far, no call |
---|
482 | boost::bind(f, "incompatible")(); // error, "incompatible" is not an int |
---|
483 | boost::bind(f, _1); // OK |
---|
484 | boost::bind(f, _1)("incompatible"); // error, "incompatible" is not an int |
---|
485 | } |
---|
486 | </pre> |
---|
487 | <h3><a name="err_arg_access">Accessing an argument that does not exist</a></h3> |
---|
488 | <p>The placeholder <b>_N</b> selects the argument at position <b>N</b> from the |
---|
489 | argument list passed at "call time." Naturally, it is an error to attempt to |
---|
490 | access beyond the end of this list:</p> |
---|
491 | <pre>int f(int); |
---|
492 | |
---|
493 | int main() |
---|
494 | { |
---|
495 | boost::bind(f, _1); // OK |
---|
496 | boost::bind(f, _1)(); // error, there is no argument number 1 |
---|
497 | } |
---|
498 | </pre> |
---|
499 | <p>The error is usually reported in <b>bind.hpp</b>, at a line similar to:</p> |
---|
500 | <pre> return f(a[a1_]); |
---|
501 | </pre> |
---|
502 | <p>When emulating <tt>std::bind1st(f, a)</tt>, a common mistake of this category is |
---|
503 | to type <tt>bind(f, a, _2)</tt> instead of the correct <tt>bind(f, a, _1)</tt>.</p> |
---|
504 | <h3><a name="err_short_form">Inappropriate use of bind(f, ...)</a></h3> |
---|
505 | <p>The <tt>bind(f, a1, a2, ..., aN)</tt> <A href="#Q_forms">form</A> causes |
---|
506 | automatic recognition of the type of <b>f</b>. It will not work with arbitrary |
---|
507 | function objects; <b>f</b> must be a function or a member function pointer.</p> |
---|
508 | <p>It is possible to use this form with function objects that define <b>result_type</b>, |
---|
509 | but <b>only on compilers</b> that support partial specialization and partial |
---|
510 | ordering. In particular, MSVC up to version 7.0 does not support this syntax |
---|
511 | for function objects.</p> |
---|
512 | <h3><a name="err_long_form">Inappropriate use of bind<R>(f, ...)</a></h3> |
---|
513 | <p>The <tt>bind<R>(f, a1, a2, ..., aN)</tt> <A href="#Q_forms">form</A> supports |
---|
514 | arbitrary function objects.</p> |
---|
515 | <p>It is possible (but not recommended) to use this form with functions or member |
---|
516 | function pointers, but <b>only on compilers</b> that support partial ordering. |
---|
517 | In particular, MSVC up to version 7.0 does not fully support this syntax for |
---|
518 | functions and member function pointers.</p> |
---|
519 | <h3><a name="err_nonstd">Binding a nonstandard function</a></h3> |
---|
520 | <p>By default, the <tt>bind(f, a1, a2, ..., aN)</tt> <A href="#Q_forms">form</A> recognizes |
---|
521 | "ordinary" C++ functions and function pointers. <A href="#stdcall">Functions that |
---|
522 | use a different calling convention</A>, or variable-argument functions such |
---|
523 | as <STRONG>std::printf</STRONG>, do not work. The general <tt>bind<R>(f, a1, |
---|
524 | a2, ..., aN)</tt> <A href="#Q_forms">form</A> works with nonstandard |
---|
525 | functions. |
---|
526 | </p> |
---|
527 | <p>On some platforms, extern "C" functions, like <b>std::strcmp</b>, are not |
---|
528 | recognized by the short form of bind. |
---|
529 | </p> |
---|
530 | <P>See also <A href="#stdcall">"__stdcall" and "pascal" Support</A>.</P> |
---|
531 | <h3><a name="err_const_arg"><b>const</b> in signatures</a></h3> |
---|
532 | <p>Some compilers, including MSVC 6.0 and Borland C++ 5.5.1, have problems with the |
---|
533 | top-level <b>const</b> in function signatures: |
---|
534 | </p> |
---|
535 | <pre>int f(int const); |
---|
536 | |
---|
537 | int main() |
---|
538 | { |
---|
539 | boost::bind(f, 1); // error |
---|
540 | } |
---|
541 | </pre> |
---|
542 | <p>Workaround: remove the <b>const</b> qualifier from the argument. |
---|
543 | </p> |
---|
544 | <h3><a name="err_msvc_using">MSVC specific: using boost::bind;</a></h3> |
---|
545 | <p>On MSVC (up to version 7.0), when <b>boost::bind</b> is brought into scope with |
---|
546 | an using declaration: |
---|
547 | </p> |
---|
548 | <pre>using boost::bind; |
---|
549 | </pre> |
---|
550 | <p>the syntax <tt>bind<R>(f, ...)</tt> does not work. Workaround: either use |
---|
551 | the qualified name, <b>boost::bind</b>, or use an using directive instead: |
---|
552 | </p> |
---|
553 | <pre>using namespace boost; |
---|
554 | </pre> |
---|
555 | <h3><a name="err_msvc_class_template">MSVC specific: class templates shadow function |
---|
556 | templates</a></h3> |
---|
557 | <p>On MSVC (up to version 7.0), a nested class template named <b>bind</b> will |
---|
558 | shadow the function template <b>boost::bind</b>, breaking the <tt>bind<R>(f, |
---|
559 | ...)</tt> syntax. Unfortunately, some libraries contain nested class |
---|
560 | templates named <b>bind</b> (ironically, such code is often an MSVC specific |
---|
561 | workaround.)</p> |
---|
562 | <P>The workaround is to use the alternative <tt>bind(type<R>(), f, ...)</tt> syntax.</P> |
---|
563 | <h3><a name="err_msvc_ellipsis">MSVC specific: ... in signatures treated as type</a></h3> |
---|
564 | <p>MSVC (up to version 7.0) treats the ellipsis in a variable argument function |
---|
565 | (such as <b>std::printf</b>) as a type. Therefore, it will accept the |
---|
566 | (incorrect in the current implementation) form: |
---|
567 | </p> |
---|
568 | <pre> bind(printf, "%s\n", _1); |
---|
569 | </pre> |
---|
570 | <p>and will reject the correct version: |
---|
571 | </p> |
---|
572 | <pre> bind<int>(printf, "%s\n", _1); |
---|
573 | </pre> |
---|
574 | <h2><a name="Interface">Interface</a></h2> |
---|
575 | <h3><a name="Synopsis">Synopsis</a></h3> |
---|
576 | <pre>namespace boost |
---|
577 | { |
---|
578 | |
---|
579 | // no arguments |
---|
580 | |
---|
581 | template<class R, class F> <i>unspecified-1</i> <A href="#bind_1" >bind</A>(F f); |
---|
582 | |
---|
583 | template<class F> <i>unspecified-1-1</i> <A href="#bind_1_1" >bind</A>(F f); |
---|
584 | |
---|
585 | template<class R> <i>unspecified-2</i> <A href="#bind_2" >bind</A>(R (*f) ()); |
---|
586 | |
---|
587 | // one argument |
---|
588 | |
---|
589 | template<class R, class F, class A1> <i>unspecified-3</i> <A href="#bind_3" >bind</A>(F f, A1 a1); |
---|
590 | |
---|
591 | template<class F, class A1> <i>unspecified-3-1</i> <A href="#bind_3_1" >bind</A>(F f, A1 a1); |
---|
592 | |
---|
593 | template<class R, class B1, class A1> <i>unspecified-4</i> <A href="#bind_4" >bind</A>(R (*f) (B1), A1 a1); |
---|
594 | |
---|
595 | template<class R, class T, class A1> <i>unspecified-5</i> <A href="#bind_5" >bind</A>(R (T::*f) (), A1 a1); |
---|
596 | |
---|
597 | template<class R, class T, class A1> <i>unspecified-6</i> <A href="#bind_6" >bind</A>(R (T::*f) () const, A1 a1); |
---|
598 | |
---|
599 | template<class R, class T, class A1> <i>unspecified-6-1</i> <A href="#bind_6_1" >bind</A>(R T::*f, A1 a1); |
---|
600 | |
---|
601 | // two arguments |
---|
602 | |
---|
603 | template<class R, class F, class A1, class A2> <i>unspecified-7</i> <A href="#bind_7" >bind</A>(F f, A1 a1, A2 a2); |
---|
604 | |
---|
605 | template<class F, class A1, class A2> <i>unspecified-7-1</i> <A href="#bind_7_1" >bind</A>(F f, A1 a1, A2 a2); |
---|
606 | |
---|
607 | template<class R, class B1, class B2, class A1, class A2> <i>unspecified-8</i> <A href="#bind_8" >bind</A>(R (*f) (B1, B2), A1 a1, A2 a2); |
---|
608 | |
---|
609 | template<class R, class T, class B1, class A1, class A2> <i>unspecified-9</i> <A href="#bind_9" >bind</A>(R (T::*f) (B1), A1 a1, A2 a2); |
---|
610 | |
---|
611 | template<class R, class T, class B1, class A1, class A2> <i>unspecified-10</i> <A href="#bind_10" >bind</A>(R (T::*f) (B1) const, A1 a1, A2 a2); |
---|
612 | |
---|
613 | // implementation defined number of additional overloads for more arguments |
---|
614 | |
---|
615 | } |
---|
616 | |
---|
617 | namespace |
---|
618 | { |
---|
619 | |
---|
620 | <i>unspecified-placeholder-type-1</i> _1; |
---|
621 | |
---|
622 | <i>unspecified-placeholder-type-2</i> _2; |
---|
623 | |
---|
624 | <i>unspecified-placeholder-type-3</i> _3; |
---|
625 | |
---|
626 | // implementation defined number of additional placeholder definitions |
---|
627 | |
---|
628 | } |
---|
629 | </pre> |
---|
630 | <h3><a name="CommonRequirements">Common requirements</a></h3> |
---|
631 | <p>All <tt><i>unspecified-N</i></tt> types returned by <b>bind</b> are <b>CopyConstructible</b>. |
---|
632 | <tt><i>unspecified-N</i>::result_type</tt> is defined as the return type of <tt><i>unspecified-N</i>::operator()</tt>.</p> |
---|
633 | <p>All <tt><i>unspecified-placeholder-N</i></tt> types are <b>CopyConstructible</b>. |
---|
634 | Their copy constructors do not throw exceptions.</p> |
---|
635 | <h3><a name="CommonDefinitions">Common definitions</a></h3> |
---|
636 | <p>The function µ(x, v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), where m is |
---|
637 | a nonnegative integer, is defined as:</p> |
---|
638 | <ul> |
---|
639 | <li> |
---|
640 | <tt>x.get()</tt>, when <tt>x</tt> is of type <tt><A href="ref.html">boost::reference_wrapper</A><T></tt> |
---|
641 | for some type <tt>T</tt>; |
---|
642 | <li> |
---|
643 | v<sub>k</sub>, when <tt>x</tt> |
---|
644 | is (a copy of) the placeholder _k for some positive integer k; |
---|
645 | <li> |
---|
646 | <tt>x(v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>)</tt> when <tt>x</tt> is |
---|
647 | (a copy of) a function object returned by <b>bind</b>; |
---|
648 | <li> |
---|
649 | <tt>x</tt> otherwise.</li></ul> |
---|
650 | <h3><a name="bind">bind</a></h3> |
---|
651 | <h4><a name="bind_1">template<class R, class F> <i>unspecified-1</i> bind(F f)</a></h4> |
---|
652 | <blockquote> |
---|
653 | <p><b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>, |
---|
654 | v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>()</tt>, |
---|
655 | implicitly converted to <b>R</b>.</p> |
---|
656 | <p><b>Throws:</b> Nothing unless the copy constructor of <b>F</b> throws an |
---|
657 | exception.</p> |
---|
658 | </blockquote> |
---|
659 | <h4><a name="bind_1_1">template<class F> <i>unspecified-1-1</i> bind(F f)</a></h4> |
---|
660 | <blockquote> |
---|
661 | <p><b>Effects:</b> Equivalent to <tt>bind<typename F::result_type, F>(f);</tt></p> |
---|
662 | <p><b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via |
---|
663 | other means as an extension, without relying on the <tt>result_type</tt> member.</p> |
---|
664 | </blockquote> |
---|
665 | <h4><a name="bind_2">template<class R> <i>unspecified-2</i> bind(R (*f) ())</a></h4> |
---|
666 | <blockquote> |
---|
667 | <p><b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>, |
---|
668 | v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>()</tt>.</p> |
---|
669 | <p><b>Throws:</b> Nothing.</p> |
---|
670 | </blockquote> |
---|
671 | <h4><a name="bind_3">template<class R, class F, class A1> <i>unspecified-3</i> bind(F |
---|
672 | f, A1 a1)</a></h4> |
---|
673 | <blockquote> |
---|
674 | <p><b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>, |
---|
675 | v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>, |
---|
676 | v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>))</tt>, implicitly |
---|
677 | converted to <b>R</b>.</p> |
---|
678 | <p><b>Throws:</b> Nothing unless the copy constructors of <b>F</b> or <b>A1</b> throw |
---|
679 | an exception.</p> |
---|
680 | </blockquote> |
---|
681 | <h4><a name="bind_3_1">template<class F, class A1> <i>unspecified-3-1</i> bind(F |
---|
682 | f, A1 a1)</a></h4> |
---|
683 | <blockquote> |
---|
684 | <p><b>Effects:</b> Equivalent to <tt>bind<typename F::result_type, F, A1>(f, a1);</tt></p> |
---|
685 | <p><b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via |
---|
686 | other means as an extension, without relying on the <tt>result_type</tt> member.</p> |
---|
687 | </blockquote> |
---|
688 | <h4><a name="bind_4">template<class R, class B1, class A1> <i>unspecified-4</i> bind(R |
---|
689 | (*f) (B1), A1 a1)</a></h4> |
---|
690 | <blockquote> |
---|
691 | <p><b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>, |
---|
692 | v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>, |
---|
693 | v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>))</tt>.</p> |
---|
694 | <p><b>Throws:</b> Nothing unless the copy constructor of <b>A1</b> throws an |
---|
695 | exception.</p> |
---|
696 | </blockquote> |
---|
697 | <h4><a name="bind_5">template<class R, class T, class A1> <i>unspecified-5</i> bind(R |
---|
698 | (T::*f) (), A1 a1)</a></h4> |
---|
699 | <blockquote> |
---|
700 | <p><b>Effects:</b> Equivalent to <tt>bind<R>(<A href="mem_fn.html">boost::mem_fn</A>(f), |
---|
701 | a1);</tt></p> |
---|
702 | </blockquote> |
---|
703 | <h4><a name="bind_6">template<class R, class T, class A1> <i>unspecified-6</i> bind(R |
---|
704 | (T::*f) () const, A1 a1)</a></h4> |
---|
705 | <blockquote> |
---|
706 | <p><b>Effects:</b> Equivalent to <tt>bind<R>(<A href="mem_fn.html">boost::mem_fn</A>(f), |
---|
707 | a1);</tt></p> |
---|
708 | </blockquote> |
---|
709 | <h4><a name="bind_6_1">template<class R, class T, class A1> <i>unspecified-6-1</i> |
---|
710 | bind(R T::*f, A1 a1)</a></h4> |
---|
711 | <blockquote> |
---|
712 | <p><b>Effects:</b> Equivalent to <tt>bind<R>(<A href="mem_fn.html">boost::mem_fn</A>(f), |
---|
713 | a1);</tt></p> |
---|
714 | </blockquote> |
---|
715 | <h4><a name="bind_7">template<class R, class F, class A1, class A2> <i>unspecified-7</i> |
---|
716 | bind(F f, A1 a1, A2 a2)</a></h4> |
---|
717 | <blockquote> |
---|
718 | <p><b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>, |
---|
719 | v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>, |
---|
720 | v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), µ(<b>a2</b>, v<sub>1</sub>, |
---|
721 | v<sub>2</sub>, ..., v<sub>m</sub>))</tt>, implicitly converted to <b>R</b>.</p> |
---|
722 | <p><b>Throws:</b> Nothing unless the copy constructors of <b>F</b>, <b>A1</b> or <b>A2</b> |
---|
723 | throw an exception.</p> |
---|
724 | </blockquote> |
---|
725 | <h4><a name="bind_7_1">template<class F, class A1, class A2> <i>unspecified-7-1</i> |
---|
726 | bind(F f, A1 a1, A2 a2)</a></h4> |
---|
727 | <blockquote> |
---|
728 | <p><b>Effects:</b> Equivalent to <tt>bind<typename F::result_type, F, A1, A2>(f, |
---|
729 | a1, a2);</tt></p> |
---|
730 | <p><b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via |
---|
731 | other means as an extension, without relying on the <tt>result_type</tt> member.</p> |
---|
732 | </blockquote> |
---|
733 | <h4><a name="bind_8">template<class R, class B1, class B2, class A1, class A2> <i>unspecified-8</i> |
---|
734 | bind(R (*f) (B1, B2), A1 a1, A2 a2)</a></h4> |
---|
735 | <blockquote> |
---|
736 | <p><b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>, |
---|
737 | v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>, |
---|
738 | v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), µ(<b>a2</b>, v<sub>1</sub>, |
---|
739 | v<sub>2</sub>, ..., v<sub>m</sub>))</tt>.</p> |
---|
740 | <p><b>Throws:</b> Nothing unless the copy constructors of <b>A1</b> or <b>A2</b> throw |
---|
741 | an exception.</p> |
---|
742 | </blockquote> |
---|
743 | <h4><a name="bind_9">template<class R, class T, class B1, class A1, class A2> <i>unspecified-9</i> |
---|
744 | bind(R (T::*f) (B1), A1 a1, A2 a2)</a></h4> |
---|
745 | <blockquote> |
---|
746 | <p><b>Effects:</b> Equivalent to <tt>bind<R>(<A href="mem_fn.html">boost::mem_fn</A>(f), |
---|
747 | a1, a2);</tt></p> |
---|
748 | </blockquote> |
---|
749 | <h4><a name="bind_10">template<class R, class T, class B1, class A1, class A2> <i>unspecified-10</i> |
---|
750 | bind(R (T::*f) (B1) const, A1 a1, A2 a2)</a></h4> |
---|
751 | <blockquote> |
---|
752 | <p><b>Effects:</b> Equivalent to <tt>bind<R>(<A href="mem_fn.html">boost::mem_fn</A>(f), |
---|
753 | a1, a2);</tt></p> |
---|
754 | </blockquote> |
---|
755 | <h3><a name="AdditionalOverloads">Additional overloads</a></h3> |
---|
756 | <p>Implementations are allowed to provide additional <b>bind</b> overloads in order |
---|
757 | to support more arguments or different function pointer variations.</p> |
---|
758 | <h2><a name="Implementation">Implementation</a></h2> |
---|
759 | <h3><a name="Files">Files</a></h3> |
---|
760 | <ul> |
---|
761 | <li> |
---|
762 | <A href="../../boost/bind.hpp">boost/bind.hpp</A> |
---|
763 | (main header) |
---|
764 | <li> |
---|
765 | <A href="../../boost/bind/bind_cc.hpp">boost/bind/bind_cc.hpp</A> |
---|
766 | (used by bind.hpp, do not include directly) |
---|
767 | <li> |
---|
768 | <A href="../../boost/bind/bind_mf_cc.hpp">boost/bind/bind_mf_cc.hpp</A> |
---|
769 | (used by bind.hpp, do not include directly) |
---|
770 | <li> |
---|
771 | <A href="../../boost/bind/bind_template.hpp">boost/bind/bind_template.hpp</A> |
---|
772 | (used by bind.hpp, do not include directly) |
---|
773 | <LI> |
---|
774 | <A href="../../boost/bind/arg.hpp">boost/bind/arg.hpp</A> |
---|
775 | (defines the type of the placeholder arguments) |
---|
776 | <LI> |
---|
777 | <A href="../../boost/bind/placeholders.hpp">boost/bind/placeholders.hpp</A> |
---|
778 | (defines the _1, _2, ... _9 placeholders) |
---|
779 | <LI> |
---|
780 | <A href="../../boost/bind/apply.hpp">boost/bind/apply.hpp</A> (<STRONG>apply</STRONG> |
---|
781 | helper function object) |
---|
782 | <LI> |
---|
783 | <A href="../../boost/bind/protect.hpp">boost/bind/protect.hpp</A> (<STRONG>protect</STRONG> |
---|
784 | helper function) |
---|
785 | <LI> |
---|
786 | <A href="../../boost/bind/make_adaptable.hpp">boost/bind/make_adaptable.hpp</A> |
---|
787 | (<STRONG>make_adaptable</STRONG> |
---|
788 | helper function) |
---|
789 | <li> |
---|
790 | <A href="test/bind_test.cpp">libs/bind/test/bind_test.cpp</A> |
---|
791 | (test) |
---|
792 | <li> |
---|
793 | <A href="bind_as_compose.cpp">libs/bind/bind_as_compose.cpp</A> |
---|
794 | (function composition example) |
---|
795 | <li> |
---|
796 | <A href="bind_visitor.cpp">libs/bind/bind_visitor.cpp</A> |
---|
797 | (visitor example) |
---|
798 | <li> |
---|
799 | <A href="test/bind_stdcall_test.cpp">libs/bind/test/bind_stdcall_test.cpp</A> |
---|
800 | (test with __stdcall functions) |
---|
801 | <li> |
---|
802 | <A href="test/bind_stdcall_mf_test.cpp">libs/bind/test/bind_stdcall_mf_test.cpp</A> |
---|
803 | (test with __stdcall member functions) |
---|
804 | <li> |
---|
805 | <A href="test/bind_fastcall_test.cpp">libs/bind/test/bind_fastcall_test.cpp</A> |
---|
806 | (test with __fastcall functions) |
---|
807 | <li> |
---|
808 | <A href="test/bind_fastcall_mf_test.cpp">libs/bind/test/bind_fastcall_mf_test.cpp</A> |
---|
809 | (test with __fastcall member functions)</li></ul> |
---|
810 | <h3><a name="Dependencies">Dependencies</a></h3> |
---|
811 | <ul> |
---|
812 | <li> |
---|
813 | <A href="../config/config.htm">Boost.Config</A> |
---|
814 | <li> |
---|
815 | <A href="ref.html">boost/ref.hpp</A> |
---|
816 | <li> |
---|
817 | <A href="mem_fn.html">boost/mem_fn.hpp</A> |
---|
818 | <li> |
---|
819 | <A href="../../boost/type.hpp">boost/type.hpp</A></li> |
---|
820 | </ul> |
---|
821 | <h3><a name="NumberOfArguments">Number of Arguments</a></h3> |
---|
822 | <p>This implementation supports function objects with up to nine arguments. This is |
---|
823 | an implementation detail, not an inherent limitation of the design.</p> |
---|
824 | <h3><a name="stdcall">"__stdcall", "__cdecl", "__fastcall", and "pascal" Support</a></h3> |
---|
825 | <p>Some platforms allow several types of (member) functions that differ by their <b>calling |
---|
826 | convention</b> (the rules by which the function is invoked: how are |
---|
827 | arguments passed, how is the return value handled, and who cleans up the stack |
---|
828 | - if any.)</p> |
---|
829 | <p>For example, Windows API functions and COM interface member functions use a |
---|
830 | calling convention known as <b>__stdcall</b>.Borland VCL components use <STRONG>__fastcall</STRONG>. |
---|
831 | Mac toolbox functions use a <b>pascal</b> calling convention.</p> |
---|
832 | <p>To use <b>bind</b> with <b>__stdcall</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_STDCALL</b> |
---|
833 | before including <b><boost/bind.hpp></b>.</p> |
---|
834 | <p>To use <b>bind</b> with <b>__stdcall</b> <b>member</b> functions, <b>#define</b> |
---|
835 | the macro <b>BOOST_MEM_FN_ENABLE_STDCALL</b> before including <b><boost/bind.hpp></b>.</p> |
---|
836 | <P>To use <B>bind</B> with <B>__fastcall</B> functions, <B>#define</B> the macro <B>BOOST_BIND_ENABLE_FASTCALL</B> |
---|
837 | before including <B><boost/bind.hpp></B>.</P> |
---|
838 | <P>To use <B>bind</B> with <B>__fastcall</B> <B>member</B> functions, <B>#define</B> |
---|
839 | the macro <B>BOOST_MEM_FN_ENABLE_FASTCALL</B> before including <B><boost/bind.hpp></B>.</P> |
---|
840 | <P>To use <b>bind</b> with <b>pascal</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_PASCAL</b> |
---|
841 | before including <b><boost/bind.hpp></b>.</P> |
---|
842 | <P>To use <B>bind</B> with <B>__cdecl</B> <B>member</B> functions, <B>#define</B> the |
---|
843 | macro <B>BOOST_MEM_FN_ENABLE_CDECL</B> before including <B><boost/bind.hpp></B>.</P> |
---|
844 | <P><STRONG>It is best to define these macros in the project options, via -D on the |
---|
845 | command line, or as the first line in the translation unit (.cpp file) where |
---|
846 | bind is used.</STRONG> Not following this rule can lead to obscure errors |
---|
847 | when a header includes bind.hpp before the macro has been defined.</P> |
---|
848 | <p>[Note: this is a non-portable extension. It is not part of the interface.]</p> |
---|
849 | <p>[Note: Some compilers provide only minimal support for the <b>__stdcall</b> keyword.]</p> |
---|
850 | <h3><a name="visit_each"><b>visit_each</b> support</a></h3> |
---|
851 | <p>Function objects returned by <b>bind</b> support the experimental and |
---|
852 | undocumented, as of yet, <b>visit_each</b> enumeration interface.</p> |
---|
853 | <p>See <A href="bind_visitor.cpp">bind_visitor.cpp</A> for an example.</p> |
---|
854 | <h2><a name="Acknowledgements">Acknowledgements</a></h2> |
---|
855 | <p>Earlier efforts that have influenced the library design:</p> |
---|
856 | <ul> |
---|
857 | <li> |
---|
858 | The <a href="http://staff.cs.utu.fi/BL/">Binder Library</a> |
---|
859 | by Jaakko Järvi; |
---|
860 | <li> |
---|
861 | The <a href="../lambda/index.html">Lambda Library</a> |
---|
862 | (now part of Boost) by Jaakko Järvi and Gary Powell (the successor to the |
---|
863 | Binder Library); |
---|
864 | <li> |
---|
865 | <a href="http://more.sourceforge.net/">Extensions to the STL</a> by Petter |
---|
866 | Urkedal.</li></ul> |
---|
867 | <p>Doug Gregor suggested that a visitor mechanism would allow <b>bind</b> to |
---|
868 | interoperate with a signal/slot library.</p> |
---|
869 | <p>John Maddock fixed a MSVC-specific conflict between <b>bind</b> and the <A href="../type_traits/index.html"> |
---|
870 | type traits library</A>.</p> |
---|
871 | <p>Numerous improvements were suggested during the formal review period by Ross |
---|
872 | Smith, Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was |
---|
873 | Darin Adler. |
---|
874 | </p> |
---|
875 | <p>The precise semantics of <b>bind</b> were refined in discussions with Jaakko |
---|
876 | Järvi. |
---|
877 | </p> |
---|
878 | <p>Dave Abrahams fixed a MSVC-specific conflict between <b>bind</b> and the <A href="../utility/iterator_adaptors.htm"> |
---|
879 | iterator adaptors library</A>. |
---|
880 | </p> |
---|
881 | <p>Dave Abrahams modified <b>bind</b> and <b>mem_fn</b> to support void returns on |
---|
882 | deficient compilers. |
---|
883 | </p> |
---|
884 | <p>Mac Murrett contributed the "pascal" support enabled by |
---|
885 | BOOST_BIND_ENABLE_PASCAL. |
---|
886 | </p> |
---|
887 | <p>The alternative <tt>bind(type<R>(), f, ...)</tt> syntax was inspired by a |
---|
888 | discussion with Dave Abrahams and Joel de Guzman.</p> |
---|
889 | <p><br> |
---|
890 | <br> |
---|
891 | <br> |
---|
892 | <small>Copyright © 2001, 2002 by Peter Dimov and Multi Media Ltd. Copyright |
---|
893 | 2003-2005 Peter Dimov. Distributed under the Boost Software License, Version |
---|
894 | 1.0. See accompanying file <A href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</A> or |
---|
895 | copy at <A href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</A>.</small></p> |
---|
896 | </body> |
---|
897 | </html> |
---|