[29] | 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> |
---|