2
0
mirror of https://github.com/boostorg/bind.git synced 2026-01-21 16:52:13 +00:00
Files
bind/bind.html
Peter Dimov b63a6a5d99 HTML error fixed.
[SVN r15253]
2002-09-10 16:12:51 +00:00

1074 lines
42 KiB
HTML
Raw Permalink Blame History

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Boost: bind.hpp documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="white" style="MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%">
<table border="0" width="100%">
<tr>
<td width="277">
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
</td>
<td align="center">
<h1>bind.hpp</h1>
</td>
</tr>
<tr>
<td colspan="2" height="64">&nbsp;</td>
</tr>
</table>
<h2>Contents</h2>
<h3 style="MARGIN-LEFT: 20pt"><a href="#Purpose">Purpose</a></h3>
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_functions">Using bind with functions and
function pointers</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_function_objects">Using bind with function
objects</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_member_pointers">Using bind with pointers
to members</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#nested_binds">Using nested binds for function
composition</a></h4>
<h3 style="MARGIN-LEFT: 20pt"><a href="#Examples">Examples</a></h3>
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_algorithms">Using bind with standard
algorithms</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_boost_function">Using bind with
Boost.Function</a></h4>
<h3 style="MARGIN-LEFT: 20pt"><a href="#Limitations">Limitations</a></h3>
<h3 style="MARGIN-LEFT: 20pt"><a href="#FAQ">Frequently Asked Questions</a></h3>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_doesnt_compile">Why doesn't this compile?</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_does_compile">Why does this compile? It
should not.</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_forms">What is the difference between bind(f,
...) and bind&lt;R&gt;(f, ...)?</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_win32_api">Does <b>bind</b> work with Windows
API functions?</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_com">Does <b>bind</b> work with COM methods?</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_mac">Does <b>bind</b> work with Mac toolbox
functions?</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_extern_C">Does <b>bind</b> work with extern
"C" functions?</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_auto_stdcall">Why doesn't <b>bind</b> automatically
recognize nonstandard functions?</a></h4>
<h3 style="MARGIN-LEFT: 20pt"><a href="#Troubleshooting">Troubleshooting</a></h3>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_num_args">Incorrect number of arguments</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_signature">The function object cannot be
called with the specified arguments</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_arg_access">Accessing an argument that does
not exist</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_short_form">Inappropriate use of bind(f,
...)</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_long_form">Inappropriate use of
bind&lt;R&gt;(f, ...)</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_nonstd">Binding a nonstandard function</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_const_arg"><b>const</b> in signatures</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_msvc_using">MSVC specific: using
boost::bind;</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_msvc_class_template">MSVC specific: class
templates shadow function templates</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#err_msvc_ellipsis">MSVC specific: ... in
signatures treated as type</a></h4>
<h3 style="MARGIN-LEFT: 20pt"><a href="#Interface">Interface</a></h3>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Synopsis">Synopsis</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#CommonRequirements">Common requirements</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#CommonDefinitions">Common definitions</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#bind">bind</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#AdditionalOverloads">Additional overloads</a></h4>
<h3 style="MARGIN-LEFT: 20pt"><a href="#Implementation">Implementation</a></h3>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Files">Files</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#Dependencies">Dependencies</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#NumberOfArguments">Number of Arguments</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall", "__fastcall",&nbsp;and
"pascal" Support</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#BOOST_BIND">Using the BOOST_BIND macro</a></h4>
<h4 style="MARGIN-LEFT: 40pt"><a href="#visit_each"><b>visit_each</b> support</a></h4>
<h3 style="MARGIN-LEFT: 20pt"><a href="#Acknowledgements">Acknowledgements</a></h3>
<h2><a name="Purpose">Purpose</a></h2>
<p>
<b>boost::bind</b> is a generalization of the standard functions <b>std::bind1st</b>
and <b>std::bind2nd</b>. It supports arbitrary function objects, functions,
function pointers, and member function pointers, and is able to bind any
argument to a specific value or route input arguments into arbitrary positions. <b>bind</b>
does not place any requirements on the function object; in particular, it does
not need the <b>result_type</b>, <b>first_argument_type</b> and <b>second_argument_type</b>
standard typedefs.
</p>
<h3><a name="with_functions">Using bind with functions and function pointers</a></h3>
<p>
Given these definitions:
</p>
<pre>
int f(int a, int b)
{
return a + b;
}
int g(int a, int b, int c)
{
return a + b + c;
}
</pre>
<p>
<tt>bind(f, 1, 2)</tt> will produce a "nullary" function object that takes no
arguments and returns <tt>f(1, 2)</tt>. Similarly, <tt>bind(g, 1, 2, 3)()</tt> is
equivalent to <tt>g(1, 2, 3)</tt>.
</p>
<p>
It is possible to selectively bind only some of the arguments. <tt>bind(f, _1,
5)(x)</tt> is equivalent to <tt>f(x, 5)</tt>; here <b>_1</b>
is a placeholder argument that means "substitute with the first input
argument."
<p>
For comparison, here is the same operation expressed with the standard library
primitives:
</p>
<pre>
std::bind2nd(std::ptr_fun(f), 5)(x);
</pre>
<p>
<b>bind</b> covers the functionality of <b>std::bind1st</b> as well:
</p>
<pre>
std::bind1st(std::ptr_fun(f), 5)(x); // f(5, x)
bind(f, 5, _1)(x); // f(5, x)
</pre>
<p>
<b>bind</b> can handle functions with more than two arguments, and its argument
substitution mechanism is more general:
</p>
<pre>
bind(f, _2, _1)(x, y); // f(y, x)
bind(g, _1, 9, _1)(x); // g(x, 9, x)
bind(g, _3, _3, _3)(x, y, z); // g(z, z, z)
bind(g, _1, _1, _1)(x, y, z); // g(x, x, x)
</pre>
<p>
Note that, in the last example, the function object produced by <tt>bind(g, _1, _1,
_1)</tt> does not contain references to any arguments beyond the first, but
it can still be used with more than one argument. Any extra arguments are
silently ignored, just like the first and the second argument are ignored in
the third example.
</p>
<p>
The arguments that <b>bind</b> takes are copied and held internally by the
returned function object. For example, in the following code:
</p>
<pre>
int i = 5;
bind(f, i, _1);
</pre>
<p>
a copy of the value of <b>i</b> is stored into the function object. <a href="ref.html">
boost::ref</a> and <a href="ref.html">boost::cref</a> can be used to make
the function object store a reference to an object, rather than a copy:
</p>
<pre>
int i = 5;
bind(f, ref(i), _1);
</pre>
<h3><a name="with_function_objects">Using bind with function objects</a></h3>
<p>
<b>bind</b> is not limited to functions; it accepts arbitrary function objects.
In the general case, the return type of the generated function object's <b>operator()</b>
has to be specified explicitly (without a <b>typeof</b> operator the return
type cannot be inferred):
</p>
<pre>
struct F
{
int operator()(int a, int b) { return a - b; }
bool operator()(long a, long b) { return a == b; }
};
F f;
int x = 104;
bind&lt;int&gt;(f, _1, _1)(x); // f(x, x), i.e. zero
</pre>
<p>
When the function object exposes a nested type named <b>result_type</b>, the
explicit return type can be omitted:
</p>
<pre>
int x = 8;
bind(std::less&lt;int&gt;(), _1, 9)(x); // x &lt; 9
</pre>
<p>
[Note: the ability to omit the return type is not available on all compilers.]
</p>
<h3><a name="with_member_pointers">Using bind with pointers to members</a></h3>
<p>
Pointers to member functions and pointers to data members are not function
objects, because they do not support <tt>operator()</tt>. For convenience, <b>bind</b>
accepts member pointers as its first argument, and the behavior is as if <a href="mem_fn.html">
boost::mem_fn</a> has been used to convert the member pointer into a
function object. In other words, the expression
</p>
<pre>
bind(&amp;X::f, <i>args</i>)
</pre>
<p>
is equivalent to
</p>
<pre>
bind&lt;R&gt;(<a href="mem_fn.html">mem_fn</a>(&amp;X::f), <i>args</i>)
</pre>
<p>
where <b>R</b> is the return type of <b>X::f</b> (for member functions) or a
const reference to the type of the member (for data members.)
</p>
<p>
[Note: <b>mem_fn</b> creates function objects that are able to accept a
pointer, a reference, or a smart pointer to an object as its first argument;
for additional information, see the <b>mem_fn</b> <a href="mem_fn.html">documentation</a>.]
</p>
<p>
Example:
</p>
<pre>
struct X
{
bool f(int a);
};
X x;
shared_ptr&lt;X&gt; p(new X);
int i = 5;
bind(&amp;X::f, ref(x), _1)(i); // x.f(i)
bind(&amp;X::f, &amp;x, _1)(i); //(&amp;x)-&gt;f(i)
bind(&amp;X::f, x, _1)(i); // (<i>internal copy of x</i>).f(i)
bind(&amp;X::f, p, _1)(i); // (<i>internal copy of p</i>)-&gt;f(i)
</pre>
<p>
The last two examples are interesting in that they produce "self-contained"
function objects. <tt>bind(&amp;X::f, x, _1)</tt> stores a copy of <b>x</b>. <tt>bind(&amp;X::f,
p, _1)</tt> stores a copy of <b>p</b>, and since <b>p</b> is a <a href="../smart_ptr/shared_ptr.htm">
boost::shared_ptr</a>, the function object retains a reference to its
instance of <b>X</b> and will remain valid even when <b>p</b> goes out of scope
or is <b>reset()</b>.
</p>
<h3><a name="nested_binds">Using nested binds for function composition</a></h3>
<p>
Some of the arguments passed to <b>bind</b> may be nested <b>bind</b> expressions
themselves:
</p>
<pre>
bind(f, bind(g, _1))(x); // f(g(x))
</pre>
<p>
The inner <STRONG>bind</STRONG> expressions are evaluated, in unspecified
order, before the outer <STRONG>bind</STRONG> when the function object is
called; the results of the evaluation are then substituted in their place when
the outer <STRONG>bind</STRONG> is evaluated. In the example above, when the
function object is called with the argument list <tt>(x)</tt>, <tt>bind(g, _1)(x)</tt>
is evaluated first, yielding <tt>g(x)</tt>, and then <tt>bind(f, g(x))(x)</tt> is
evaluated, yielding the final result <tt>f(g(x))</tt>.
</p>
<P>
This feature of <b>bind</b> can be used to perform function composition. See <a href="bind_as_compose.cpp">
bind_as_compose.cpp</a> for an example that demonstrates how to use <b>bind</b>
to achieve similar functionality to <a href="../compose/index.htm">Boost.Compose</a>.
</P>
<p>
Note that the first argument - the bound function object - is not evaluated,
even when it's a function object that is produced by <STRONG>bind</STRONG> or a
placeholder argument, so the example below does not work as expected:
</p>
<pre>
typedef void (*pf)(int);
std::vector&lt;pf&gt; v;
std::for_each(v.begin(), v.end(), bind(_1, 5));
</pre>
<p>
The desired effect can be achieved via a helper function object <STRONG>apply</STRONG>
that applies its first argument, as a function object, to the rest of its
argument list. For convenience, an implementation of <STRONG>apply</STRONG> is
provided in the <STRONG>boost/bind/apply.hpp</STRONG> header file. Here is how
the modified version of the previous example looks like:
</p>
<pre>
typedef void (*pf)(int);
std::vector&lt;pf&gt; v;
std::for_each(v.begin(), v.end(), bind(apply&lt;void&gt;(), _1, 5));
</pre>
<P>Sometimes it is necessary not to evaluate the first argument, but <STRONG>not</STRONG>
to evaluate some of the other arguments, even when they are nested <STRONG>bind</STRONG>
subexpressions. This can be achieved with the help of another function object, <STRONG>
protect</STRONG>, that masks the type so that <STRONG>bind</STRONG> does
not recognize and evaluate it. When called, <STRONG>protect</STRONG> simply
forwards the argument list to the other function object unmodified.</P>
<P>The header <STRONG>boost/bind/protect.hpp</STRONG> contains an implementation of <STRONG>
protect</STRONG>. To protect a <STRONG>bind</STRONG> function object from
evaluation, use <tt>protect(bind(f, ...))</tt>.</P>
<h2><a name="Examples">Examples</a></h2>
<h3><a name="with_algorithms">Using bind with standard algorithms</a></h3>
<pre>
class image;
class animation
{
public:
void advance(int ms);
bool inactive() const;
void render(image &amp; target) const;
};
std::vector&lt;animation&gt; anims;
template&lt;class C, class P&gt; void erase_if(C &amp; c, P pred)
{
c.erase(std::remove_if(c.begin(), c.end(), pred), c.end());
}
void update(int ms)
{
std::for_each(anims.begin(), anims.end(), boost::bind(&amp;animation::advance, _1, ms));
erase_if(anims, boost::mem_fn(&amp;animation::inactive));
}
void render(image &amp; target)
{
std::for_each(anims.begin(), anims.end(), boost::bind(&amp;animation::render, _1, boost::ref(target)));
}
</pre>
<h3><a name="with_boost_function">Using bind with Boost.Function</a></h3>
<pre>
class button
{
public:
<a href="../function/index.html">boost::function</a>&lt;void&gt; onClick;
};
class player
{
public:
void play();
void stop();
};
button playButton, stopButton;
player thePlayer;
void connect()
{
playButton.onClick = boost::bind(&amp;player::play, &amp;thePlayer);
stopButton.onClick = boost::bind(&amp;player::stop, &amp;thePlayer);
}
</pre>
<h3><a name="Limitations">Limitations</a></h3>
<p>
The function objects generated by <b>bind</b> take their arguments by reference
and cannot, therefore, accept non-const temporaries or literal constants. This
is an inherent limitation of the C++ language, known as the "forwarding
function problem."
</p>
<p>
The library uses signatures of the form
</p>
<pre>
template&lt;class T&gt; void f(T &amp; t);
</pre>
<p>
to accept arguments of arbitrary types and pass them on unmodified. As noted,
this does not work with non-const r-values.
</p>
<p>
An oft-proposed "solution" to this problem is to add an overload:
</p>
<pre>
template&lt;class T&gt; void f(T &amp; t);
template&lt;class T&gt; void f(T const &amp; t);
</pre>
<p>
Unfortunately, this (a) requires providing 512 overloads for nine arguments and
(b) does not actually work for const arguments, both l- and r-values, since the
two templates produce the exact same signature and cannot be partially ordered.
</p>
<p>
[Note: this is a dark corner of the language, and the <a href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#214">
corresponding issue</a> has not been resolved yet.]
</p>
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
<h3><a name="Q_doesnt_compile">Why doesn't this compile?</a></h3>
<p>
See the <a href="#Troubleshooting">dedicated Troubleshooting section</a>.
</p>
<h3><a name="Q_does_compile">Why does this compile? It should not.</a></h3>
<p>
Probably because you used the general bind&lt;R&gt;(f, ...) syntax, thereby
instructing <b>bind</b> to not "inspect" <b>f</b> to detect arity and return
type errors.
</p>
<h3><a name="Q_forms">What is the difference between bind(f, ...) and bind&lt;R&gt;(f,
...)?</a></h3>
<p>
The first form instructs <b>bind</b> to inspect the type of <b>f</b> in order
to determine its arity (number of arguments) and return type. Arity errors will
be detected at "bind time". This syntax, of course, places some requirements on <b>f</b>.
It must be a function, function pointer, member function pointer, or a function
object that defines a nested type named <b>result_type</b>; in short, it must
be something that <b>bind</b> can recognize.
</p>
<p>
The second form instructs <b>bind</b> to <b>not</b> attempt to recognize the
type of <b>f</b>. It is generally used with function objects that do not, or
cannot, expose <b>result_type</b>, but it can also be used with nonstandard
functions. For example, the current implementation does not automatically
recognize variable-argument functions like <b>printf</b>, so you will have to
use <tt>bind&lt;int&gt;(printf, ...)</tt>.
</p>
<p>
Another important factor to consider is that compilers without partial template
specialization or function template partial ordering support cannot handle the
first form when <b>f</b> is a function object, and in most cases will not
handle the second form when <b>f</b> is a function (pointer) or a member
function pointer.
</p>
<h3><a name="Q_win32_api">Does <b>bind</b> work with Windows API functions?</a></h3>
<p>
Yes, if you <a href="#stdcall">#define BOOST_BIND_ENABLE_STDCALL</a>. An
alternative is to treat the function as a <a href="#with_function_objects">generic
function object</a> and use the bind&lt;R&gt;(f, ...) syntax.
</p>
<h3><a name="Q_com">Does <b>bind</b> work with COM methods?</a></h3>
<p>
Yes, if you <a href="#stdcall">#define BOOST_MEM_FN_ENABLE_STDCALL</a>.
</p>
<h3><a name="Q_mac">Does <b>bind</b> work with Mac toolbox functions?</a></h3>
<p>
Yes, if you <a href="#stdcall">#define BOOST_BIND_ENABLE_PASCAL</a>. An
alternative is to treat the function as a <a href="#with_function_objects">generic
function object</a> and use the bind&lt;R&gt;(f, ...) syntax.
</p>
<h3><a name="Q_extern_C">Does <b>bind</b> work with extern "C" functions?</a></h3>
<p>
Sometimes. On some platforms, pointers to extern "C" functions are equivalent
to "ordinary" function pointers, so they work fine. Other platforms treat them
as different types. A platform-specific implementation of <b>bind</b> is
expected to handle the problem transparently; this implementation does not. As
usual, the workaround is to treat the function as a <a href="#with_function_objects">
generic function object</a> and use the bind&lt;R&gt;(f, ...) syntax.
</p>
<h3><a name="Q_auto_stdcall">Why doesn't <b>bind</b> automatically recognize
nonstandard functions?</a></h3>
<p>
Non-portable extensions, in general, should default to off to prevent vendor
lock-in. Had the <a href="#stdcall">appropriate macros</a> been defined
automatically, you could have accidentally taken advantage of them without
realizing that your code is, perhaps, no longer portable. In addition, some
compilers have the option to make <b>__stdcall</b> (<STRONG>__fastcall</STRONG>)
their default calling convention, in which case no separate support would be
necessary.
</p>
<h2><a name="Troubleshooting">Troubleshooting</a></h2>
<h3><a name="err_num_args">Incorrect number of arguments</a></h3>
<p>
In a bind(f, a1, a2, ..., aN) expression, the function object <b>f</b> must be
able to take exactly <b>N</b> arguments. This error is normally detected at
"bind time"; in other words, the compilation error is reported on the line
where bind() is invoked:
</p>
<pre>
int f(int, int);
int main()
{
boost::bind(f, 1); // error, f takes two arguments
boost::bind(f, 1, 2); // OK
}
</pre>
<p>
A common variation of this error is to forget that member functions have an
implicit "this" argument:
</p>
<pre>
struct X
{
int f(int);
}
int main()
{
boost::bind(&amp;X::f, 1); // error, X::f takes two arguments
boost::bind(&amp;X::f, <b>_1</b>, 1); // OK
}
</pre>
<h3><a name="err_signature">The function object cannot be called with the specified
arguments</a></h3>
<p>
As in normal function calls, the function object that is bound must be
compatible with the argument list. The incompatibility will usually be detected
by the compiler at "call time" and the result is typically an error in <b>bind.hpp</b>
on a line that looks like:
</p>
<pre>
return f(a[a1_], a[a2_]);
</pre>
<p>
An example of this kind of error:
</p>
<pre>
int f(int);
int main()
{
boost::bind(f, "incompatible"); // OK so far, no call
boost::bind(f, "incompatible")(); // error, "incompatible" is not an int
boost::bind(f, _1); // OK
boost::bind(f, _1)("incompatible"); // error, "incompatible" is not an int
}
</pre>
<h3><a name="err_arg_access">Accessing an argument that does not exist</a></h3>
<p>
The placeholder <b>_N</b> selects the argument at position <b>N</b> from the
argument list passed at "call time." Naturally, it is an error to attempt to
access beyond the end of this list:
</p>
<pre>
int f(int);
int main()
{
boost::bind(f, _1); // OK
boost::bind(f, _1)(); // error, there is no argument number 1
}
</pre>
<p>
The error is usually reported in <b>bind.hpp</b>, at a line similar to:
</p>
<pre>
return f(a[a1_]);
</pre>
<p>
When emulating <b>std::bind1st(f, a)</b>, a common mistake of this category is
to type <b>bind(f, a, _2)</b> instead of the correct <b>bind(f, a, _1)</b>.
</p>
<h3><a name="err_short_form">Inappropriate use of bind(f, ...)</a></h3>
<p>
The bind(f, a1, a2, ..., aN) <a href="#Q_forms">form</a> causes automatic
recognition of the type of <b>f</b>. It will not work with arbitrary function
objects; <b>f</b> must be a function or a member function pointer.
</p>
<p>
It is possible to use this form with function objects that define <b>result_type</b>,
but <b>only on compilers</b> that support partial specialization and partial
ordering. In particular, MSVC up to version 7.0 does not support this syntax
for function objects.
</p>
<h3><a name="err_long_form">Inappropriate use of bind&lt;R&gt;(f, ...)</a></h3>
<p>
The bind&lt;R&gt;(f, a1, a2, ..., aN) <a href="#Q_forms">form</a> supports
arbitrary function objects.
</p>
<p>
It is possible (but not recommended) to use this form with functions or member
function pointers, but <b>only on compilers</b> that support partial ordering.
In particular, MSVC up to version 7.0 does not fully support this syntax for
functions and member function pointers.
</p>
<h3><a name="err_nonstd">Binding a nonstandard function</a></h3>
<p>
By default, the bind(f, a1, a2, ..., aN) <A href="#Q_forms">form</A> recognizes
"ordinary" C++ functions and function pointers. <A href="#stdcall">Functions that
use a different calling convention</A>, or variable-argument functions such
as <STRONG>std::printf</STRONG>, do not work. The general bind&lt;R&gt;(f, a1,
a2, ..., aN) <A href="#Q_forms">form</A> works with nonstandard functions.
</p>
<p>
On some platforms, extern "C" functions, like <b>std::strcmp</b>, are not
recognized by the short form of bind.
</p>
<P>
See also <A href="#stdcall" name="stdcall">"__stdcall" and "pascal" Support</A>.</P>
<h3><a name="err_const_arg"><b>const</b> in signatures</a></h3>
<p>
Some compilers, including MSVC 6.0 and Borland C++ 5.5.1, have problems with
the top-level <b>const</b> in function signatures:
</p>
<pre>
int f(int const);
int main()
{
boost::bind(f, 1); // error
}
</pre>
<p>
Workaround: remove the <b>const</b> qualifier from the argument.
</p>
<h3><a name="err_msvc_using">MSVC specific: using boost::bind;</a></h3>
<p>
On MSVC (up to version 7.0), when <b>boost::bind</b> is brought into scope with
an using declaration:
</p>
<pre>
using boost::bind;
</pre>
<p>
the syntax <b>bind&lt;R&gt;(...)</b> does not work. Workaround: either use the
qualified name, <b>boost::bind</b>, or use an using directive instead:
</p>
<pre>
using namespace boost;
</pre>
<h3><a name="err_msvc_class_template">MSVC specific: class templates shadow function
templates</a></h3>
<p>
On MSVC (up to version 7.0), a nested class template named <b>bind</b> will
shadow the function template <b>boost::bind</b>, breaking the <b>bind&lt;R&gt;(...)</b>
syntax. Unfortunately, some libraries contain nested class templates named <b>bind</b>
(ironically, such code is often an MSVC specific workaround.) You may try to
patch the library in question or contact its author/maintainer. The other
option is use the <a href="#BOOST_BIND">BOOST_BIND</a> macro to rename <b>bind</b>.
</p>
<h3><a name="err_msvc_ellipsis">MSVC specific: ... in signatures treated as type</a></h3>
<p>
MSVC (up to version 7.0) treats the ellipsis in a variable argument function
(such as <b>std::printf</b>) as a type. Therefore, it will accept the
(incorrect in the current implementation) form:
</p>
<pre>
bind(printf, "%s\n", _1);
</pre>
<p>
and will reject the correct version:
</p>
<pre>
bind&lt;int&gt;(printf, "%s\n", _1);
</pre>
<h2><a name="Interface">Interface</a></h2>
<h3><a name="Synopsis">Synopsis</a></h3>
<pre>
namespace boost
{
// no arguments
template&lt;class R, class F&gt; <i>unspecified-1</i> <a href="#bind_1">bind</a>(F f);
template&lt;class F&gt; <i>unspecified-1-1</i> <a href="#bind_1_1">bind</a>(F f);
template&lt;class R&gt; <i>unspecified-2</i> <a href="#bind_2">bind</a>(R (*f) ());
// one argument
template&lt;class R, class F, class A1&gt; <i>unspecified-3</i> <a href="#bind_3">bind</a>(F f, A1 a1);
template&lt;class F, class A1&gt; <i>unspecified-3-1</i> <a href="#bind_3_1">bind</a>(F f, A1 a1);
template&lt;class R, class B1, class A1&gt; <i>unspecified-4</i> <a href="#bind_4">bind</a>(R (*f) (B1), A1 a1);
template&lt;class R, class T, class A1&gt; <i>unspecified-5</i> <a href="#bind_5">bind</a>(R (T::*f) (), A1 a1);
template&lt;class R, class T, class A1&gt; <i>unspecified-6</i> <a href="#bind_6">bind</a>(R (T::*f) () const, A1 a1);
template&lt;class R, class T, class A1&gt; <i>unspecified-6-1</i> <a href="#bind_6_1">bind</a>(R T::*f, A1 a1);
// two arguments
template&lt;class R, class F, class A1, class A2&gt; <i>unspecified-7</i> <a href="#bind_7">bind</a>(F f, A1 a1, A2 a2);
template&lt;class F, class A1, class A2&gt; <i>unspecified-7-1</i> <a href="#bind_7_1">bind</a>(F f, A1 a1, A2 a2);
template&lt;class R, class B1, class B2, class A1, class A2&gt; <i>unspecified-8</i> <a href="#bind_8">bind</a>(R (*f) (B1, B2), A1 a1, A2 a2);
template&lt;class R, class T, class B1, class A1, class A2&gt; <i>unspecified-9</i> <a href="#bind_9">bind</a>(R (T::*f) (B1), A1 a1, A2 a2);
template&lt;class R, class T, class B1, class A1, class A2&gt; <i>unspecified-10</i> <a href="#bind_10">bind</a>(R (T::*f) (B1) const, A1 a1, A2 a2);
// implementation defined number of additional overloads for more arguments
}
namespace
{
<i>unspecified-placeholder-type-1</i> _1;
<i>unspecified-placeholder-type-2</i> _2;
<i>unspecified-placeholder-type-3</i> _3;
// implementation defined number of additional placeholder definitions
}
</pre>
<h3><a name="CommonRequirements">Common requirements</a></h3>
<p>
All <tt><i>unspecified-N</i></tt> types returned by <b>bind</b> are <b>CopyConstructible</b>.
<tt><i>unspecified-N</i>::result_type</tt> is defined as the return type of <tt><i>unspecified-N</i>::operator()</tt>.
</p>
<p>
All <tt><i>unspecified-placeholder-N</i></tt> types are <b>CopyConstructible</b>.
Their copy constructors do not throw exceptions.
</p>
<h3><a name="CommonDefinitions">Common definitions</a></h3>
<p>
The function <20>(x, v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), where m is
a nonnegative integer, is defined as:
</p>
<ul>
<li>
<tt>x.get()</tt>, when <tt>x</tt> is of type <tt><a href="ref.html">boost::reference_wrapper</a>&lt;T&gt;</tt>
for some type <tt>T</tt>;
<li>
v<sub>k</sub>, when <tt>x</tt>
is (a copy of) the placeholder _k for some positive integer k;
<li>
<tt>x(v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>)</tt> when <tt>x</tt> is
(a copy of) a function object returned by <b>bind</b>;
<li>
<tt>x</tt> otherwise.</li>
</ul>
<h3><a name="bind">bind</a></h3>
<h4><a name="bind_1">template&lt;class R, class F&gt; <i>unspecified-1</i> bind(F f)</a></h4>
<blockquote>
<p>
<b>Returns:</b> A function object <i>&#955;</i> such that the expression <tt>&#955;(v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>()</tt>,
implicitly converted to <b>R</b>.
</p>
<p>
<b>Throws:</b> Nothing unless the copy constructor of <b>F</b> throws an
exception.
</p>
</blockquote>
<h4><a name="bind_1_1">template&lt;class F&gt; <i>unspecified-1-1</i> bind(F f)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;typename F::result_type, F&gt;(f);</tt>
</p>
<p>
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
other means as an extension, without relying on the <tt>result_type</tt> member.
</p>
</blockquote>
<h4><a name="bind_2">template&lt;class R&gt; <i>unspecified-2</i> bind(R (*f) ())</a></h4>
<blockquote>
<p>
<b>Returns:</b> A function object <i>&#955;</i> such that the expression <tt>&#955;(v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>()</tt>.
</p>
<p>
<b>Throws:</b> Nothing.
</p>
</blockquote>
<h4><a name="bind_3">template&lt;class R, class F, class A1&gt; <i>unspecified-3</i> bind(F
f, A1 a1)</a></h4>
<blockquote>
<p>
<b>Returns:</b> A function object <i>&#955;</i> such that the expression <tt>&#955;(v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(<28>(<b>a1</b>,
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>))</tt>, implicitly
converted to <b>R</b>.
</p>
<p>
<b>Throws:</b> Nothing unless the copy constructors of <b>F</b> or <b>A1</b> throw
an exception.
</p>
</blockquote>
<h4><a name="bind_3_1">template&lt;class F, class A1&gt; <i>unspecified-3-1</i> bind(F
f, A1 a1)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;typename F::result_type, F, A1&gt;(f,
a1);</tt>
</p>
<p>
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
other means as an extension, without relying on the <tt>result_type</tt> member.
</p>
</blockquote>
<h4><a name="bind_4">template&lt;class R, class B1, class A1&gt; <i>unspecified-4</i> bind(R
(*f) (B1), A1 a1)</a></h4>
<blockquote>
<p>
<b>Returns:</b> A function object <i>&#955;</i> such that the expression <tt>&#955;(v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(<28>(<b>a1</b>,
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>))</tt>.
</p>
<p>
<b>Throws:</b> Nothing unless the copy constructor of <b>A1</b> throws an
exception.
</p>
</blockquote>
<h4><a name="bind_5">template&lt;class R, class T, class A1&gt; <i>unspecified-5</i> bind(R
(T::*f) (), A1 a1)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;R&gt;(<a href="mem_fn.html">boost::mem_fn</a>(f),
a1);</tt>
</p>
</blockquote>
<h4><a name="bind_6">template&lt;class R, class T, class A1&gt; <i>unspecified-6</i> bind(R
(T::*f) () const, A1 a1)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;R&gt;(<a href="mem_fn.html">boost::mem_fn</a>(f),
a1);</tt>
</p>
</blockquote>
<h4><a name="bind_6_1">template&lt;class R, class T, class A1&gt; <i>unspecified-6-1</i>
bind(R T::*f, A1 a1)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;R const &amp;&gt;(<a href="mem_fn.html">boost::mem_fn</a>(f),
a1);</tt>
</p>
</blockquote>
<h4><a name="bind_7">template&lt;class R, class F, class A1, class A2&gt; <i>unspecified-7</i>
bind(F f, A1 a1, A2 a2)</a></h4>
<blockquote>
<p>
<b>Returns:</b> A function object <i>&#955;</i> such that the expression <tt>&#955;(v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(<28>(<b>a1</b>,
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), <20>(<b>a2</b>, v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>))</tt>, implicitly converted to <b>R</b>.
</p>
<p>
<b>Throws:</b> Nothing unless the copy constructors of <b>F</b>, <b>A1</b> or <b>A2</b>
throw an exception.
</p>
</blockquote>
<h4><a name="bind_7_1">template&lt;class F, class A1, class A2&gt; <i>unspecified-7-1</i>
bind(F f, A1 a1, A2 a2)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;typename F::result_type, F, A1, A2&gt;(f,
a1, a2);</tt>
</p>
<p>
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
other means as an extension, without relying on the <tt>result_type</tt> member.
</p>
</blockquote>
<h4><a name="bind_8">template&lt;class R, class B1, class B2, class A1, class A2&gt; <i>unspecified-8</i>
bind(R (*f) (B1, B2), A1 a1, A2 a2)</a></h4>
<blockquote>
<p>
<b>Returns:</b> A function object <i>&#955;</i> such that the expression <tt>&#955;(v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(<28>(<b>a1</b>,
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), <20>(<b>a2</b>, v<sub>1</sub>,
v<sub>2</sub>, ..., v<sub>m</sub>))</tt>.
</p>
<p>
<b>Throws:</b> Nothing unless the copy constructors of <b>A1</b> or <b>A2</b> throw
an exception.
</p>
</blockquote>
<h4><a name="bind_9">template&lt;class R, class T, class B1, class A1, class A2&gt; <i>unspecified-9</i>
bind(R (T::*f) (B1), A1 a1, A2 a2)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;R&gt;(<a href="mem_fn.html">boost::mem_fn</a>(f),
a1, a2);</tt>
</p>
</blockquote>
<h4><a name="bind_10">template&lt;class R, class T, class B1, class A1, class A2&gt; <i>unspecified-10</i>
bind(R (T::*f) (B1) const, A1 a1, A2 a2)</a></h4>
<blockquote>
<p>
<b>Effects:</b> Equivalent to <tt>bind&lt;R&gt;(<a href="mem_fn.html">boost::mem_fn</a>(f),
a1, a2);</tt>
</p>
</blockquote>
<h3><a name="AdditionalOverloads">Additional overloads</a></h3>
<p>
Implementations are allowed to provide additional <b>bind</b> overloads in
order to support more arguments or different function pointer variations.
</p>
<h2><a name="Implementation">Implementation</a></h2>
<h3><a name="Files">Files</a></h3>
<ul>
<li>
<a href="../../boost/bind.hpp">boost/bind.hpp</a>
(main header)
<li>
<a href="../../boost/bind/bind_cc.hpp">boost/bind/bind_cc.hpp</a>
(used by bind.hpp, do not include directly)
<li>
<a href="../../boost/bind/bind_mf_cc.hpp">boost/bind/bind_mf_cc.hpp</a>
(used by bind.hpp, do not include directly)
<li>
<a href="../../boost/bind/bind_template.hpp">boost/bind/bind_template.hpp</a>
(used by bind.hpp, do not include directly)
<LI>
<A href="../../boost/bind/arg.hpp">boost/bind/arg.hpp</A>
(defines the type of the placeholder arguments)
<LI>
<A href="../../boost/bind/placeholders.hpp">boost/bind/placeholders.hpp</A>
(defines the _1, _2, ... _9 placeholders)
<LI>
<A href="../../boost/bind/apply.hpp">boost/bind/apply.hpp</A> (<STRONG>apply</STRONG>
helper function object)
<LI>
<A href="../../boost/bind/protect.hpp">boost/bind/protect.hpp</A> (<STRONG>protect</STRONG>
helper function)
<LI>
<A href="../../boost/bind/make_adaptable.hpp">boost/bind/make_adaptable.hpp</A>
(<STRONG>make_adaptable</STRONG>
helper function)
<li>
<a href="bind_test.cpp">libs/bind/bind_test.cpp</a>
(test)
<li>
<a href="bind_as_compose.cpp">libs/bind/bind_as_compose.cpp</a>
(function composition example)
<li>
<a href="bind_visitor.cpp">libs/bind/bind_visitor.cpp</a>
(visitor example)
<li>
<a href="bind_stdcall_test.cpp">libs/bind/bind_stdcall_test.cpp</a>
(test with __stdcall functions)
<li>
<a href="bind_stdcall_mf_test.cpp">libs/bind/bind_stdcall_mf_test.cpp</a> (test
with __stdcall member functions)</li>
<li>
<a href="bind_fastcall_test.cpp">libs/bind/bind_fastcall_test.cpp</a>
(test with __fastcall functions)
<li>
<a href="bind_fastcall_mf_test.cpp">libs/bind/bind_fastcall_mf_test.cpp</a> (test
with __fastcall member functions)</li>
</ul>
<h3><a name="Dependencies">Dependencies</a></h3>
<ul>
<li>
<a href="../config/config.htm">Boost.Config</a>
<li>
<a href="ref.html">boost/ref.hpp</a>
<li>
<a href="mem_fn.html">boost/mem_fn.hpp</a></li>
</ul>
<h3><a name="NumberOfArguments">Number of Arguments</a></h3>
<p>
This implementation supports function objects with up to nine arguments. This
is an implementation detail, not an inherent limitation of the design.
</p>
<h3><a name="stdcall">"__stdcall", "__fastcall", and "pascal" Support</a></h3>
<p>
Some platforms allow several types of (member) functions that differ by their <b>calling
convention</b> (the rules by which the function is invoked: how are
arguments passed, how is the return value handled, and who cleans up the stack
- if any.)
</p>
<p>
For example, Windows API functions and COM interface member functions use a
calling convention known as <b>__stdcall</b>.Borland VCL components use <STRONG>__fastcall</STRONG>.
Mac toolbox functions use a <b>pascal</b> calling convention.
</p>
<p>
To use <b>bind</b> with <b>__stdcall</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_STDCALL</b>
before including <b>&lt;boost/bind.hpp&gt;</b>.
</p>
<p>
To use <b>bind</b> with <b>__stdcall</b> <b>member</b> functions, <b>#define</b>
the macro <b>BOOST_MEM_FN_ENABLE_STDCALL</b> before including <b>&lt;boost/bind.hpp&gt;</b>.
</p>
<P>To use <B>bind</B> with <B>__fastcall</B> functions, <B>#define</B> the macro <B>BOOST_BIND_ENABLE_FASTCALL</B>
before including <B>&lt;boost/bind.hpp&gt;</B>.
</P>
<P>To use <B>bind</B> with <B>__fastcall</B> <B>member</B> functions, <B>#define</B>
the macro <B>BOOST_MEM_FN_ENABLE_FASTCALL</B> before including <B>&lt;boost/bind.hpp&gt;</B>.
</P>
<P>
To use <b>bind</b> with <b>pascal</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_PASCAL</b>
before including <b>&lt;boost/bind.hpp&gt;</b>.
</P>
<p>
[Note: this is a non-portable extension. It is not part of the interface.]
</p>
<p>
[Note: Some compilers provide only minimal support for the <b>__stdcall</b> keyword.]
</p>
<h3><a name="BOOST_BIND">Using the BOOST_BIND macro</a></h3>
<p>
A <a href="#err_msvc_class_template">bug in MSVC (up to version 7.0)</a> causes <b>boost::bind</b>
to be incompatible with libraries that contain nested class templates named <b>bind</b>.
To work around this problem, <b>#define</b> the macro <b>BOOST_BIND</b> to
something other than <b>bind</b> (before the inclusion of <b>&lt;boost/bind.hpp&gt;</b>)
and use this identifier throughout your code wherever you'd normally use <b>bind</b>.
</p>
<p style="COLOR: red">
[Note: BOOST_BIND is not a general renaming mechanism. It is not part of the
interface, and is not guaranteed to work on other compilers, or persist between
library versions. In short, don't use it unless you absolutely have to.]
</p>
<h3><a name="visit_each"><b>visit_each</b> support</a></h3>
<p>
Function objects returned by <b>bind</b> support the experimental and
undocumented, as of yet, <b>visit_each</b> enumeration interface.
</p>
<p>
See <a href="bind_visitor.cpp">bind_visitor.cpp</a> for an example.
</p>
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
<p>
Earlier efforts that have influenced the library design:
</p>
<ul>
<li>
The <a href="http://staff.cs.utu.fi/BL/">Binder Library</a>
by Jaakko J<>rvi;
<li>
The <a href="http://lambda.cs.utu.fi/">Lambda Library</a>
by Jaakko J<>rvi and Gary Powell (the successor to the Binder Library);
<li>
<a href="http://matfys.lth.se/~petter/src/more/stlext/index.html">Extensions to the
STL</a> by Petter Urkedal.</li>
</ul>
<p>
Doug Gregor suggested that a visitor mechanism would allow <b>bind</b> to
interoperate with a signal/slot library.
</p>
<p>
John Maddock fixed a MSVC-specific conflict between <b>bind</b> and the <a href="../type_traits/index.htm">
type traits library</a>.
</p>
<p>
Numerous improvements were suggested during the formal review period by Ross
Smith, Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was
Darin Adler.
</p>
<p>
The precise semantics of <b>bind</b> were refined in discussions with Jaakko
J<>rvi.
</p>
<p>
Dave Abrahams fixed a MSVC-specific conflict between <b>bind</b> and the <a href="../utility/iterator_adaptors.htm">
iterator adaptors library</a>.
</p>
<p>
Dave Abrahams modified <b>bind</b> and <b>mem_fn</b> to support void returns on
deficient compilers.
</p>
<p>
Mac Murrett contributed the "pascal" support enabled by
BOOST_BIND_ENABLE_PASCAL.
</p>
<p><br>
<br>
<br>
<small>Copyright <20> 2001, 2002 by Peter Dimov and Multi Media Ltd. Permission to
copy, use, modify, sell and distribute this document is granted provided this
copyright notice appears in all copies. This document is provided "as is"
without express or implied warranty, and with no claim as to its suitability
for any purpose.</small></p>
</body>
</html>