From bdde6cd8b2fdc6fa12a5def772624c6fb5a1f383 Mon Sep 17 00:00:00 2001
From: Peter Dimov
[Note: the ability to omit the return type is not available on all compilers.]
- Pointers to member functions are not function objects, because they do not
- support operator(). For convenience, bind accepts member
- function pointers as its first argument, and the behavior is as if
- boost::mem_fn has been used to convert the member function pointer into
- a function object. In other words, the expression
+ Pointers to member functions and pointers to data members are not function
+ objects, because they do not support operator(). For convenience, bind
+ accepts member pointers as its first argument, and the behavior is as if
+ boost::mem_fn has been used to convert the member pointer into a
+ function object. In other words, the expression
- where R is the return type of X::f.
+ where R is the return type of X::f (for member functions) or a
+ const reference to the type of the member (for data members.)
[Note: mem_fn creates function objects that are able to accept a
@@ -260,13 +264,13 @@ bind(&X::f, p, _1)(i); // (internal copy of p)->f(i)
bind(f, bind(g, _1))(x); // f(g(x))
- The inner bind expressions are evaluated, in
- unspecified order, before the outer bind when the
- function object is called; the results of the evaluation are then substituted
- in their place when the outer bind is evaluated. In the
- example above, when the function object is called with the argument list (x),
- bind(g, _1)(x) is evaluated first, yielding g(x), and then bind(f,
- g(x))(x) is evaluated, yielding the final result f(g(x)).
+ The inner bind expressions are evaluated, in unspecified
+ order, before the outer bind when the function object is
+ called; the results of the evaluation are then substituted in their place when
+ the outer bind is evaluated. In the example above, when the
+ function object is called with the argument list (x), bind(g, _1)(x)
+ is evaluated first, yielding g(x), and then bind(f, g(x))(x) is
+ evaluated, yielding the final result f(g(x)).
This feature of bind can be used to perform function composition. See
@@ -289,8 +293,8 @@ std::for_each(v.begin(), v.end(), bind(_1, 5));
The desired effect can be achieved via a helper function object apply
that applies its first argument, as a function object, to the rest of its
argument list. For convenience, an implementation of apply is
- provided in the boost/bind/apply.hpp header file. Here is
- how the modified version of the previous example looks like:
+ provided in the boost/bind/apply.hpp header file. Here is how
+ the modified version of the previous example looks like:
Using bind with function
objects
- Using bind with member
- function pointers
+ Using bind with pointers
+ to members
Using nested binds for function
composition
Examples
@@ -45,6 +45,8 @@
Does bind work with COM methods?
Does bind work with Mac toolbox
functions?
+ Does bind work with extern
+ "C" functions?
Why doesn't bind automatically
recognize nonstandard functions?
Troubleshooting
@@ -70,6 +72,7 @@
Common requirements
Common definitions
bind
+ Additional overloads
Implementation
Files
Dependencies
@@ -198,13 +201,13 @@ bind(std::less<int>(), _1, 9)(x); // x < 9
Using bind with member function pointers
+ Using bind with pointers to members
bind(&X::f, args)
@@ -216,7 +219,8 @@ bind(&X::f, args)
bind<R>(mem_fn(&X::f), args)
typedef void (*pf)(int);
@@ -305,9 +309,9 @@ std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));
protect, that masks the type so that bind does
not recognize and evaluate it. When called, protect simply
forwards the argument list to the other function object unmodified.
The header boost/bind/protect.hpp contains an - implementation of protect. To protect a bind - function object from evaluation, use protect(bind(f, ...)).
+The header boost/bind/protect.hpp contains an implementation of + protect. To protect a bind function object from + evaluation, use protect(bind(f, ...)).
@@ -451,6 +455,15 @@ template<class T> void f(T const & t); alternative is to treat the function as a generic function object and use the bind<R>(f, ...) syntax. +Does bind work with extern "C" functions?
++ 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 bind + is expected to handle the problem transparently; this implementation does not. + As usual, the workaround is to treat the function as a + generic function object and use the bind<R>(f, ...) syntax. +
Why doesn't bind automatically recognize nonstandard functions?
@@ -570,10 +583,14 @@ int main()
Binding a nonstandard function
By default, the bind(f, a1, a2, ..., aN) form recognizes - "ordinary" C++ functions and function pointers. Functions that use - a different calling convention, or variable-argument functions - such as std::printf, do not work. The general bind<R>(f, - a1, a2, ..., aN) form works with nonstandard functions. + "ordinary" C++ functions and function pointers. Functions that + use a different calling convention, or variable-argument functions such + as std::printf, do not work. The general bind<R>(f, a1, + a2, ..., aN) form works with nonstandard functions. +
++ On some platforms, extern "C" functions, like std::strcmp, are not + recognized by the short form of bind.
See also "__stdcall" and "pascal" Support.
@@ -641,35 +658,37 @@ namespace boost // no arguments -template<class R, class F> implementation-defined-1 bind(F f); +template<class R, class F> unspecified-1 bind(F f); -template<class F> implementation-defined-1-1 bind(F f); +template<class F> unspecified-1-1 bind(F f); -template<class R> implementation-defined-2 bind(R (*f) ()); +template<class R> unspecified-2 bind(R (*f) ()); // one argument -template<class R, class F, class A1> implementation-defined-3 bind(F f, A1 a1); +template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1); -template<class F, class A1> implementation-defined-3-1 bind(F f, A1 a1); +template<class F, class A1> unspecified-3-1 bind(F f, A1 a1); -template<class R, class B1, class A1> implementation-defined-4 bind(R (*f) (B1), A1 a1); +template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1); -template<class R, class T, class A1> implementation-defined-5 bind(R (T::*f) (), A1 a1); +template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1); -template<class R, class T, class A1> implementation-defined-6 bind(R (T::*f) () const, A1 a1); +template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1); + +template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1); // two arguments -template<class R, class F, class A1, class A2> implementation-defined-7 bind(F f, A1 a1, A2 a2); +template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2); -template<class F, class A1, class A2> implementation-defined-7-1 bind(F f, A1 a1, A2 a2); +template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2); -template<class R, class B1, class B2, class A1, class A2> implementation-defined-8 bind(R (*f) (B1, B2), A1 a1, A2 a2); +template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2); -template<class R, class T, class B1, class A1, class A2> implementation-defined-9 bind(R (T::*f) (B1), A1 a1, A2 a2); +template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2); -template<class R, class T, class B1, class A1, class A2> implementation-defined-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2); +template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2); // implementation defined number of additional overloads for more arguments @@ -678,11 +697,11 @@ template<class R, class T, class B1, class A1, class A2> implementation namespace { -implementation-defined-placeholder-type-1 _1; +unspecified-placeholder-type-1 _1; -implementation-defined-placeholder-type-2 _2; +unspecified-placeholder-type-2 _2; -implementation-defined-placeholder-type-3 _3; +unspecified-placeholder-type-3 _3; // implementation defined number of additional placeholder definitions @@ -690,12 +709,11 @@ namespace
- All implementation-defined-N types returned by bind are CopyConstructible. - implementation-defined-N::result_type is defined as the return - type of implementation-defined-N::operator(). + All unspecified-N types returned by bind are CopyConstructible. + unspecified-N::result_type is defined as the return type of unspecified-N::operator().
- All implementation-defined-placeholder-N types are CopyConstructible. + All unspecified-placeholder-N types are CopyConstructible. Their copy constructors do not throw exceptions.
-- Returns: a function object λ such that the expression λ(v1, + Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(), implicitly converted to R.
@@ -730,29 +747,31 @@ namespace exception.
-- Effects: equivalent to bind<typename F::result_type, F>(f); + Effects: Equivalent to bind<typename F::result_type, F>(f); +
++ Notes: Implementations are allowed to infer the return type of f + via other means as an extension, without relying on the result_type member.
-- Returns: a function object λ such that the expression λ(v1, + Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f().
Throws: Nothing.
-- Returns: a function object λ such that the expression λ(v1, + Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm)), implicitly converted to R. @@ -762,19 +781,23 @@ namespace an exception.
-- Effects: equivalent to bind<typename F::result_type, F, A1>(f, + Effects: Equivalent to bind<typename F::result_type, F, A1>(f, a1);
++ Notes: Implementations are allowed to infer the return type of f + via other means as an extension, without relying on the result_type member. +
-- Returns: a function object λ such that the expression λ(v1, + Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm)).
@@ -783,27 +806,35 @@ namespace exception.
-- Effects: equivalent to bind<R>(boost::mem_fn(f), + Effects: Equivalent to bind<R>(boost::mem_fn(f), a1);
-- Effects: equivalent to bind<R>(boost::mem_fn(f), + Effects: Equivalent to bind<R>(boost::mem_fn(f), a1);
+++ Effects: Equivalent to bind<R const &>(boost::mem_fn(f), + a1); +
+
-- Returns: a function object λ such that the expression λ(v1, + Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm), µ(a2, v1, v2, ..., vm)), implicitly converted to R. @@ -813,19 +844,23 @@ namespace throw an exception.
-- Effects: equivalent to bind<typename F::result_type, F, A1, A2>(f, + Effects: Equivalent to bind<typename F::result_type, F, A1, A2>(f, a1, a2);
++ Notes: Implementations are allowed to infer the return type of f + via other means as an extension, without relying on the result_type member. +
-- Returns: a function object λ such that the expression λ(v1, + Returns: A function object λ such that the expression λ(v1, v2, ..., vm) is equivalent to f(µ(a1, v1, v2, ..., vm), µ(a2, v1, v2, ..., vm)). @@ -835,22 +870,27 @@ namespace an exception.
-- Effects: equivalent to bind<R>(boost::mem_fn(f), + Effects: Equivalent to bind<R>(boost::mem_fn(f), a1, a2);
+- Effects: equivalent to bind<R>(boost::mem_fn(f), + Effects: Equivalent to bind<R>(boost::mem_fn(f), a1, a2);
+ Implementations are allowed to provide additional bind overloads in order to + support more arguments or different function pointer variations. +
- Copyright © 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"
+ Copyright © 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.