diff --git a/doc/.gitignore b/doc/.gitignore deleted file mode 100644 index ac7af2e..0000000 --- a/doc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/html/ diff --git a/doc/html/bind.html b/doc/html/bind.html new file mode 100644 index 0000000..9a2b0a9 --- /dev/null +++ b/doc/html/bind.html @@ -0,0 +1,1552 @@ + +
+ +![]() |
+Home | +Libraries | +People | +FAQ | +More | +
Copyright © 2001, 2002 Peter Dimov and Multi Media Ltd.
Copyright © 2003-2008 Peter Dimov
+ Distributed under the Boost + Software License, Version 1.0. +
+Table of Contents
+bind(f, ...)
and
+ bind<R>(f, ...)
?bind(f, ...)
bind<R>(f, ...)
const
in signaturesusing boost::bind;
...
in signatures treated
+ as type
+ boost::bind
is a generalization of the standard
+ functions std::bind1st
and std::bind2nd
.
+ 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. bind
+ does not place any requirements on the function object; in particular, it does
+ not need the result_type
,
+ first_argument_type
and second_argument_type
standard typedefs.
+
+ Given these definitions: +
+int f(int a, int b) +{ + return a + b; +} + +int g(int a, int b, int c) +{ + return a + b + c; +} ++
+ bind(f, 1, 2)
+ will produce a "nullary" function object that takes no arguments
+ and returns f(1, 2)
. Similarly, bind(g,
+ 1, 2, 3)()
is equivalent to
+ g(1, 2, 3)
.
+
+ It is possible to selectively bind only some of the arguments. bind(f, _1,
+ 5)(x)
is equivalent
+ to f(x, 5)
; here _1
+ is a placeholder argument that means "substitute
+ with the first input argument."
+
+ For comparison, here is the same operation expressed with the standard library + primitives: +
+std::bind2nd(std::ptr_fun(f), 5)(x); ++
+ bind
covers the functionality
+ of std::bind1st
as well:
+
std::bind1st(std::ptr_fun(f), 5)(x); // f(5, x) +bind(f, 5, _1)(x); // f(5, x) ++
+ bind
can handle functions
+ with more than two arguments, and its argument substitution mechanism is
+ more general:
+
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) ++
+ Note that, in the last example, the function object produced by bind(g, _1,
+ _1, _1)
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.
+
+ The arguments that bind
takes
+ are copied and held internally by the returned function object. For example,
+ in the following code:
+
int i = 5; +bind(f, i, _1); ++
+ a copy of the value of i
+ is stored into the function object. boost::ref
and boost::cref
can be used to make the function
+ object store a reference to an object, rather than a copy:
+
int i = 5; +bind(f, ref(i), _1); +bind(f, cref(i), _1); ++
+ bind
is not limited to functions;
+ it accepts arbitrary function objects. In the general case, the return type
+ of the generated function object's operator()
has to be specified explicitly (without
+ a typeof
operator the return
+ type cannot be inferred):
+
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<int>(f, _1, _1)(x); // f(x, x), i.e. zero ++
+ Some compilers have trouble with the bind<R>(f, ...)
+ syntax. For portability reasons, an alternative way to express the above
+ is supported:
+
boost::bind(boost::type<int>(), f, _1, _1)(x); ++
+ Note, however, that the alternative syntax is provided only as a workaround. + It is not part of the interface. +
+
+ When the function object exposes a nested type named result_type
,
+ the explicit return type can be omitted:
+
int x = 8; +bind(std::less<int>(), _1, 9)(x); // x < 9 ++
+ [Note: the ability to omit the return type is not available + on all compilers.] +
+
+ By default, bind
makes a
+ copy of the provided function object. boost::ref
and
+ boost::cref
can be used to make it store a reference
+ to the function object, rather than a copy. This can be useful when the function
+ object is non-copyable, expensive to copy, or contains state; of course,
+ in this case the programmer is expected to ensure that the function object
+ is not destroyed while it's still being used.
+
struct F2 +{ + int s; + + typedef void result_type; + void operator()(int x) { s += x; } +}; + +F2 f2 = { 0 }; +int a[] = { 1, 2, 3 }; + +std::for_each(a, a+3, bind(ref(f2), _1)); + +assert(f2.s == 6); ++
+ 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
+
bind(&X::f, args) ++
+ is equivalent to +
+bind<R>(mem_fn
(&X::f), args)
+
+
+ where R
is the return type
+ of X::f
(for member functions) or the type of
+ the member (for data members.)
+
+ [Note: mem_fn
+ 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 mem_fn
documentation.]
+
+ Example: +
+struct X +{ + bool f(int a); +}; + +X x; +shared_ptr<X> p(new X); +int i = 5; + +bind(&X::f, ref(x), _1)(i); // x.f(i) +bind(&X::f, &x, _1)(i); // (&x)->f(i) +bind(&X::f, x, _1)(i); // (internal copy of x).f(i) +bind(&X::f, p, _1)(i); // (internal copy of p)->f(i) ++
+ The last two examples are interesting in that they produce "self-contained"
+ function objects. bind(&X::f, x,
+ _1)
+ stores a copy of x
. bind(&X::f, p,
+ _1)
+ stores a copy of p
, and since
+ p
is a boost::shared_ptr
, the function object
+ retains a reference to its instance of X
+ and will remain valid even when p
+ goes out of scope or is reset()
.
+
+ Some of the arguments passed to bind
+ may be nested bind expressions themselves:
+
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))
.
+
+ This feature of bind
can
+ be used to perform function composition. See bind_as_compose.cpp
+ for an example that demonstrates how to use bind
+ to achieve similar functionality to Boost.Compose.
+
+ Note that the first argument - the bound function object - is not evaluated,
+ even when it's a function object that is produced by bind
+ or a placeholder argument, so the example below does
+ not work as expected:
+
typedef void (*pf)(int); + +std::vector<pf> v; +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 apply.hpp
+ header file. Here is how the modified version of the previous example looks
+ like:
+
typedef void (*pf)(int); + +std::vector<pf> v; +std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5)); ++
+ Although the first argument is, by default, not evaluated, all other arguments
+ are. Sometimes it is necessary not to evaluate arguments subsequent to the
+ first, even when they are nested bind subexpressions.
+ This can be achieved with the help of another function object, 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 protect.hpp
+ contains an implementation of protect
.
+ To protect
a bind function
+ object from evaluation, use protect(bind(f, ...))
.
+
+ For convenience, the function objects produced by bind
+ overload the logical not operator !
+ and the relational and logical operators ==,
+ !=, <,
+ <=, >,
+ >=, &&,
+ ||
.
+
+ !bind(f,
+ ...)
is equivalent to bind(logical_not(), bind(f,
+ ...))
, where logical_not
+ is a function object that takes one argument x
+ and returns !x
.
+
+ bind(f, ...)
+ op x
,
+ where op is a relational or logical
+ operator, is equivalent to bind(relation(), bind(f,
+ ...), x)
, where relation
+ is a function object that takes two arguments a
+ and b
and returns a op b
.
+
+ What this means in practice is that you can conveniently negate the result
+ of bind
:
+
std::remove_if(first, last, !bind(&X::visible, _1)); // remove invisible objects ++
+ and compare the result of bind
+ against a value:
+
std::find_if(first, last, bind(&X::name, _1) == "Peter"); +std::find_if(first, last, bind(&X::name, _1) == "Peter" || bind(&X::name, _1) == "Paul"); ++
+ against a placeholder: +
+bind(&X::name, _1) == _2 ++
+ or against another bind expression: +
+std::sort(first, last, bind(&X::name, _1) < bind(&X::name, _2)); // sort by name ++
class image; + +class animation +{ +public: + void advance(int ms); + bool inactive() const; + void render(image & target) const; +}; + +std::vector<animation> anims; + +template<class C, class P> void erase_if(C & 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(&animation::advance, _1, ms)); + erase_if(anims, boost::mem_fn(&animation::inactive)); +} + +void render(image & target) +{ + std::for_each(anims.begin(), anims.end(), boost::bind(&animation::render, _1, boost::ref(target))); +} ++
class button
+{
+public:
+ boost::function
<void()> onClick;
+};
+
+class player
+{
+public:
+ void play();
+ void stop();
+};
+
+button playButton, stopButton;
+player thePlayer;
+
+void connect()
+{
+ playButton.onClick = boost::bind(&player::play, &thePlayer);
+ stopButton.onClick = boost::bind(&player::stop, &thePlayer);
+}
+
+
+ As a general rule, the function objects generated by bind
+ take their arguments by reference and cannot, therefore, accept non-const temporaries
+ or literal constants. This is an inherent limitation of the C++ language in
+ its current (2003) incarnation, known as the forwarding
+ problem. (It will be fixed in the next standard, usually called C++0x.)
+
+ The library uses signatures of the form +
+template<class T> void f(T & t); ++
+ to accept arguments of arbitrary types and pass them on unmodified. As noted, + this does not work with non-const r-values. +
++ On compilers that support partial ordering of function templates, a possible + solution is to add an overload: +
+template<class T> void f(T & t); +template<class T> void f(T const & t); ++
+ Unfortunately, this requires providing 512 overloads for nine arguments, which + is impractical. The library chooses a small subset: for up to two arguments, + it provides the const overloads in full, for arities of three and more it provides + a single additional overload with all of the arguments taken by const reference. + This covers a reasonable portion of the use cases. +
++ See the dedicated Troubleshooting section. +
+
+ Probably because you used the general bind<R>(f, ...)
+ syntax, thereby instructing bind
+ to not "inspect" f to detect arity and return type errors.
+
+ The first form instructs bind
+ to inspect the type of f
+ 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 f
.
+ It must be a function, function pointer, member function pointer, or a function
+ object that defines a nested type named result_type
;
+ in short, it must be something that bind
+ can recognize.
+
+ The second form instructs bind
+ to not attempt to recognize the type of f
.
+ It is generally used with function objects that do not, or cannot, expose
+ result_type
, but it can also
+ be used with nonstandard functions. For example, the current implementation
+ does not automatically recognize variable-argument functions like printf
, so you will have to use bind<int>(printf, ...)
. Note
+ that an alternative bind(type<R>(), f, ...)
+ syntax is supported for portability reasons.
+
+ Another important factor to consider is that compilers without partial template
+ specialization or function template partial ordering support cannot handle
+ the first form when f
is
+ a function object, and in most cases will not handle the second form when
+ f
is a function (pointer)
+ or a member function pointer.
+
+ Yes, if you #define
+ BOOST_BIND_ENABLE_STDCALL
.
+ An alternative is to treat the function as a generic
+ function object and use the bind<R>(f, ...)
+ syntax.
+
+ Yes, if you #define
+ BOOST_MEM_FN_ENABLE_STDCALL
.
+
+ Yes, if you #define
+ BOOST_BIND_ENABLE_PASCAL
.
+ An alternative is to treat the function as a generic
+ function object and use the bind<R>(f, ...)
+ syntax.
+
+ 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.
+
+ Non-portable extensions, in general, should default to off to prevent vendor
+ lock-in. Had the appropriate
+ macros 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 __stdcall
(__fastcall
)
+ their default calling convention, in which case no separate support would
+ be necessary.
+
+ In a bind(f, a1, a2,
+ ..., aN)
expression, the function object f
must be able to take exactly N arguments.
+ This error is normally detected at "bind time"; in other words,
+ the compilation error is reported on the line where bind()
is invoked:
+
int f(int, int); + +int main() +{ + boost::bind(f, 1); // error, f takes two arguments + boost::bind(f, 1, 2); // OK +} ++
+ A common variation of this error is to forget that member functions have + an implicit "this" argument: +
+struct X +{ + int f(int); +} + +int main() +{ + boost::bind(&X::f, 1); // error, X::f takes two arguments + boost::bind(&X::f, _1, 1); // OK +} ++
+ 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
+ bind.hpp
on a line that looks like:
+
return f(a[a1_], a[a2_]); ++
+ An example of this kind of error: +
+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 +} ++
+ The placeholder _N
selects
+ the argument at position N
+ from the argument list passed at "call time." Naturally, it is
+ an error to attempt to access beyond the end of this list:
+
int f(int); + +int main() +{ + boost::bind(f, _1); // OK + boost::bind(f, _1)(); // error, there is no argument number 1 +} ++
+ The error is usually reported in bind.hpp
, at
+ a line similar to:
+
return f(a[a1_]); ++
+ When emulating std::bind1st(f, a)
, a common mistake of this category is to
+ type bind(f, a, _2)
+ instead of the correct bind(f,
+ a, _1)
.
+
+ The bind(f, a1, a2,
+ ..., aN)
form
+ causes automatic recognition of the type of f
.
+ It will not work with arbitrary function objects; f
+ must be a function or a member function pointer.
+
+ It is possible to use this form with function objects that define result_type
, but only on compilers that
+ support partial specialization and partial ordering. In particular, MSVC
+ up to version 7.0 does not support this syntax for function objects.
+
+ The bind<R>(f, a1, a2,
+ ..., aN)
form
+ supports arbitrary function objects.
+
+ It is possible (but not recommended) to use this form with functions or member + function pointers, but only on compilers that support partial ordering. In + particular, MSVC up to version 7.0 does not fully support this syntax for + functions and member function pointers. +
+
+ 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.
+
+ On some platforms, extern "C" functions, like std::strcmp
,
+ are not recognized by the short form of bind
.
+
+ See also __stdcall
+ and pascal
Support.
+
+ An attempt to bind an overloaded function usually results in an error, as + there is no way to tell which overload was meant to be bound. This is a common + problem with member functions with two overloads, const and non-const, as + in this simplified example: +
+struct X +{ + int& get(); + int const& get() const; +}; + +int main() +{ + boost::bind(&X::get, _1); +} ++
+ The ambiguity can be resolved manually by casting the (member) function pointer + to the desired type: +
+int main() +{ + boost::bind(static_cast< int const& (X::*) () const >(&X::get), _1); +} ++
+ Another, arguably more readable, alternative is to introduce a temporary + variable: +
+int main() +{ + int const& (X::*get) () const = &X::get; + boost::bind(get, _1); +} ++
+ The function objects that are produced by bind
+ do not model the STL Unary
+ Function or Binary
+ Function concepts, even when the function objects are
+ unary or binary operations, because the function object types are missing
+ public typedefs result_type
+ and argument_type
or first_argument_type
and second_argument_type
.
+ In cases where these typedefs are desirable, however, the utility function
+ make_adaptable
can be used
+ to adapt unary and binary function objects to these concepts. This allows
+ unary and binary function objects resulting from bind
+ to be combined with STL templates such as std::unary_negate
+ and std::binary_negate
.
+
+ The make_adaptable
function
+ is defined in <boost/bind/make_adaptable.hpp>
,
+ which must be included explicitly in addition to <boost/bind.hpp>
:
+
#include <boost/bind/make_adaptable.hpp> + +template <class R, class F> unspecified-type make_adaptable(F f); + +template<class R, class A1, class F> unspecified-unary-functional-type make_adaptable(F f); + +template<class R, class A1, class A2, class F> unspecified-binary-functional-type make_adaptable(F f); + +template<class R, class A1, class A2, class A3, class F> unspecified-ternary-functional-type make_adaptable(F f); + +template<class R, class A1, class A2, class A3, class A4, class F> unspecified-4-ary-functional-type make_adaptable(F f); ++
+ This example shows how to use make_adaptable
+ to make a predicate for "is not a space":
+
typedef char char_t; +std::locale loc(""); +const std::ctype<char_t>& ct = std::use_facet<std::ctype<char_t> >(loc); + +auto isntspace = std::not1(boost::make_adaptable<bool, char_t>(boost::bind(&std::ctype<char_t>::is, &ct, std::ctype_base::space, _1))); ++
+ In this example, bind
creates
+ the "is a space" (unary) predicate. It is then passed to make_adaptable
so that a function object
+ modeling the Unary Function concept can be created,
+ serving as the argument to std::not1
.
+
+ Some compilers, including MSVC 6.0 and Borland C++ 5.5.1, have problems with
+ the top-level const
in function
+ signatures:
+
int f(int const); + +int main() +{ + boost::bind(f, 1); // error +} ++
+ Workaround: remove the const
+ qualifier from the argument.
+
+ On MSVC (up to version 7.0), when boostbind
+ is brought into scope with an using declaration:
+
using boost::bind; ++
+ the syntax bind<R>(f, ...)
+ does not work. Workaround: either use the qualified name, boost::bind
,
+ or use an using directive instead:
+
using namespace boost; ++
+ On MSVC (up to version 7.0), a nested class template named bind
will shadow the function template
+ boost::bind
, breaking the bind<R>(f, ...)
syntax.
+ Unfortunately, some libraries contain nested class templates named bind
(ironically, such code is often an
+ MSVC specific workaround.)
+
+ The workaround is to use the alternative bind(type<R>(), f, ...)
+ syntax.
+
+ MSVC (up to version 7.0) treats the ellipsis in a variable argument function
+ (such as std::printf
) as a type. Therefore, it will accept
+ the (incorrect in the current implementation) form:
+
bind(printf, "%s\n", _1); ++
+ and will reject the correct version: +
+bind<int>(printf, "%s\n", _1); ++
namespace boost +{ +// no arguments + +template<class R, class F> unspecified-1+bind
(F f); + +template<class F> unspecified-1-1bind
(F f); + +template<class R> unspecified-2bind
(R (*f) ()); + +// one argument + +template<class R, class F, class A1> unspecified-3bind
(F f, A1 a1); + +template<class F, class A1> unspecified-3-1bind
(F f, A1 a1); + +template<class R, class B1, class A1> unspecified-4bind
(R (*f) (B1), A1 a1); + +template<class R, class T, class A1> unspecified-5bind
(R (T::*f) (), A1 a1); + +template<class R, class T, class A1> unspecified-6bind
(R (T::*f) () const, A1 a1); + +template<class R, class T, class A1> unspecified-6-1bind
(R T::*f, A1 a1); + +// two arguments + +template<class R, class F, class A1, class A2> unspecified-7bind
(F f, A1 a1, A2 a2); + +template<class F, class A1, class A2> unspecified-7-1bind
(F f, A1 a1, A2 a2); + +template<class R, class B1, class B2, class A1, class A2> unspecified-8bind
(R (*f) (B1, B2), A1 a1, A2 a2); + +template<class R, class T, class B1, class A1, class A2> unspecified-9bind
(R (T::*f) (B1), A1 a1, A2 a2); + +template<class R, class T, class B1, class A1, class A2> unspecified-10bind
(R (T::*f) (B1) const, A1 a1, A2 a2); + +// implementation defined number of additional overloads for more arguments +} + +namespace +{ + unspecified-placeholder-type-1 _1; + + unspecified-placeholder-type-2 _2; + + unspecified-placeholder-type-3 _3; + +// implementation defined number of additional placeholder definitions +} +
+ All unspecified-N types returned by bind
+ are CopyConstructible. unspecified-N::result_type
+ is defined as the return type of unspecified-N::operator()
.
+
+ All unspecified-placeholder-N types are CopyConstructible. + Their copy constructors do not throw exceptions. +
+
+ The function μ(x, v1,
+ v2, ..., vm)
, where m
+ is a nonnegative integer, is defined as:
+
x.get()
,
+ when x
is of type boost::reference_wrapper
<T>
for some type T
;
+ vk
, when x
is (a copy of) the placeholder _k
+ for some positive integer k;
+ x(v1, v2, ..., vm)
when x
+ is (a copy of) a function object returned by bind
;
+ x
otherwise.
+ bind
+template<class R, class F> unspecified-1 bind(F f) ++
(v1, v2, ..., vm)
+ is equivalent to f()
,
+ implicitly converted to R
.
+ F
throws an exception.
+ template<class F> unspecified-1-1 bind(F f) ++
bind<typename
+ F::result_type,
+ F>(f)
.
+ f
via
+ other means as an extension, without relying on the result_type
+ member.
+ template<class R> unspecified-2 bind(R (*f) ()) ++
(v1, v2, ..., vm)
+ is equivalent to f()
.
+ template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1) ++
(v1, v2, ..., vm)
+ is equivalent to f(
μ(a1, v1, v2, ..., vm))
,
+ implicitly converted to R
.
+ F
or A1
+ throw an exception.
+ template<class F, class A1> unspecified-3-1 bind(F f, A1 a1) ++
bind<typename
+ F::result_type,
+ F,
+ A1>(f, a1)
.
+ f
via
+ other means as an extension, without relying on the result_type
+ member.
+ template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1) ++
(v1, v2, ..., vm)
+ is equivalent to f(
μ(a1, v1, v2, ..., vm))
.
+ A1
throws an exception.
+ template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), A1 a1) ++
bind<R>(
boost::mem_fn
(f), a1)
.
+ template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1) ++
bind<R>(
boost::mem_fn
(f), a1)
.
+ template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1) ++
bind<R>(
boost::mem_fn
(f), a1)
.
+ template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2) ++
(v1, v2, ..., vm)
+ is equivalent to f(
μ(a1, v1, v2, ..., vm),
μ(a2, v1, v2, ..., vm))
,
+ implicitly converted to R
.
+ F
, A1
+ or A2
throw an exception.
+ template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2) ++
bind<typename
+ F::result_type,
+ F,
+ A1,
+ A2>(f, a1, a2)
.
+ f
via
+ other means as an extension, without relying on the result_type
+ member.
+ template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2) ++
(v1, v2, ..., vm)
+ is equivalent to f(
μ(a1, v1, v2, ..., vm),
μ(a2, v1, v2, ..., vm))
.
+ A1
or A2
+ throw an exception.
+ template<class R, class T, class B1, class A1, class A2> unspecified-9 bind(R (T::*f) (B1), A1 a1, A2 a2) ++
bind<R>(
boost::mem_fn
(f), a1, a2)
.
+ template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2) ++
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.
+
bind.hpp
, do not include directly)
+ bind.hpp
, do not include directly)
+ bind.hpp
, do not include directly)
+ _1
, _2
, ... _9
+ placeholders)
+ apply
helper function
+ object)
+ protect
helper function)
+ make_adaptable
helper
+ function)
+ __stdcall
+ functions)
+ __stdcall
+ member functions)
+ __fastcall
+ functions)
+ __fastcall
+ member functions)
+ + This implementation supports function objects with up to nine arguments. + This is an implementation detail, not an inherent limitation of the design. +
++ Some platforms allow several types of (member) functions that differ by their + calling convention (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.) +
+
+ For example, Windows API functions and COM interface member functions use
+ a calling convention known as __stdcall
.
+ Borland VCL components use __fastcall
.
+ Mac toolbox functions use a pascal
+ calling convention.
+
+ To use bind
with __stdcall
functions, #define
+ the macro BOOST_BIND_ENABLE_STDCALL
+ before including <boost/bind.hpp>
.
+
+ To use bind
with __stdcall
member functions, #define
the macro BOOST_MEM_FN_ENABLE_STDCALL
+ before including <boost/bind.hpp>
.
+
+ To use bind
with __fastcall
functions, #define
+ the macro BOOST_BIND_ENABLE_FASTCALL
+ before including <boost/bind.hpp>
.
+
+ To use bind
with __fastcall
member functions, #define
the macro BOOST_MEM_FN_ENABLE_FASTCALL
+ before including <boost/bind.hpp>
.
+
+ To use bind
with pascal
functions, #define
+ the macro BOOST_BIND_ENABLE_PASCAL
+ before including <boost/bind.hpp>
.
+
+ To use bind
with __cdecl
member functions, #define
the macro BOOST_MEM_FN_ENABLE_CDECL
+ before including <boost/bind.hpp>
.
+
+ It is best to define these macros in the project options,
+ via -D
+ on the command line, or as the first line in the translation unit (.cpp file)
+ where bind
is used.
+ Not following this rule can lead to obscure errors when a header includes
+ bind.hpp
before the macro has been defined.
+
+ [Note: this is a non-portable extension. It is not part + of the interface.] +
+
+ [Note: Some compilers provide only minimal support for
+ the __stdcall
keyword.]
+
+ Function objects returned by bind
+ support the experimental and undocumented, as of yet, visit_each
+ enumeration interface.
+
+ See bind_visitor.cpp for an example. +
++ Earlier efforts that have influenced the library design: +
+
+ Doug Gregor suggested that a visitor mechanism would allow bind
+ to interoperate with a signal/slot library.
+
+ John Maddock fixed a MSVC-specific conflict between bind
+ and the type traits library.
+
+ 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. +
+
+ The precise semantics of bind
+ were refined in discussions with Jaakko Järvi.
+
+ Dave Abrahams fixed a MSVC-specific conflict between bind
+ and the iterator adaptors
+ library.
+
+ Dave Abrahams modified bind
+ and mem_fn
to support void
returns on deficient compilers.
+
+ Mac Murrett contributed the "pascal" support enabled by BOOST_BIND_ENABLE_PASCAL
.
+
+ The alternative bind(type<R>(), f, ...)
+ syntax was inspired by a discussion with Dave Abrahams and Joel de Guzman.
+
+ This documentation was ported to Quickbook by Agustín Bergé. +
+Last revised: June 06, 2015 at 16:07:44 GMT |
++ |
![]() |
+Home | +Libraries | +People | +FAQ | +More | +
Copyright © 2001, 2002 Peter Dimov and Multi Media Ltd.
Copyright © 2003-2005 Peter Dimov
+ Distributed under the Boost + Software License, Version 1.0. +
+Table of Contents
+ +
+ boost::mem_fn
is a generalization of the standard
+ functions std::mem_fun
and std::mem_fun_ref
.
+ It supports member function pointers with more than one argument, and the returned
+ function object can take a pointer, a reference, or a smart pointer to an object
+ instance as its first argument. mem_fn
+ also supports pointers to data members by treating them as functions taking
+ no arguments and returning a (const) reference to the member.
+
+ The purpose of mem_fn
is twofold.
+ First, it allows users to invoke a member function on a container with the
+ familiar
+
std::for_each(v.begin(), v.end(), boost::mem_fn(&Shape::draw)); ++
+ syntax, even when the container stores smart pointers. +
+
+ Second, it can be used as a building block by library developers that want
+ to treat a pointer to member function as a function object. A library might
+ define an enhanced for_each
+ algorithm with an overload of the form:
+
template<class It, class R, class T> void for_each(It first, It last, R (T::*pmf) ()) +{ + std::for_each(first, last, boost::mem_fn(pmf)); +} ++
+ that will allow the convenient syntax: +
+for_each(v.begin(), v.end(), &Shape::draw); ++
+ When documenting the feature, the library author will simply state: +
+template<class It, class R, class T> void for_each(It first, It last, R (T::*pmf) ()); ++
std::for_each(first, last, boost::mem_fn(pmf))
.
+
+ where boost::mem_fn
can be a link to this page. See the
+ documentation of bind
+ for an example.
+
+ mem_fn
takes one argument,
+ a pointer to a member, and returns a function object suitable for use with
+ standard or user-defined algorithms:
+
struct X +{ + void f(); +}; + +void g(std::vector<X> & v) +{ + std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f)); +}; + +void h(std::vector<X *> const & v) +{ + std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f)); +}; + +void k(std::vector<boost::shared_ptr<X> > const & v) +{ + std::for_each(v.begin(), v.end(), boost::mem_fn(&X::f)); +}; ++
+ The returned function object takes the same arguments as the input member function + plus a "flexible" first argument that represents the object instance. +
+
+ When the function object is invoked with a first argument x
+ that is neither a pointer nor a reference to the appropriate class (X
in the example above), it uses get_pointer(x)
to obtain
+ a pointer from x
. Library authors
+ can "register" their smart pointer classes by supplying an appropriate
+ get_pointer
overload, allowing
+ mem_fn
to recognize and support
+ them.
+
+ [Note: get_pointer
+ is not restricted to return a pointer. Any object that can be used in a member
+ function call expression (x->*pmf)(...)
will work.]
+
+ [Note: the library uses an unqualified call to get_pointer
. Therefore, it will find, through
+ argument-dependent lookup, get_pointer
+ overloads that are defined in the same namespace as the corresponding smart
+ pointer class, in addition to any boost::get_pointer
+ overloads.]
+
+ All function objects returned by mem_fn
+ expose a result_type
typedef
+ that represents the return type of the member function. For data members,
+ result_type
is defined as the
+ type of the member.
+
+ Yes. For simple uses, mem_fn
+ provides additional functionality that the standard adaptors do not. Complicated
+ expressions that use std::bind1st
,
+ std::bind2nd
or Boost.Compose
+ along with the standard adaptors can be rewritten using boost::bind
+ that automatically takes advantage of mem_fn
.
+
+ No, unless you have good reasons to do so. mem_fn
+ is not 100% compatible with the standard adaptors, although it comes pretty
+ close. In particular, mem_fn
+ does not return objects of type std::[const_]mem_fun[1][_ref]_t
,
+ as the standard adaptors do, and it is not possible to fully describe the
+ type of the first argument using the standard argument_type
+ and first_argument_type
nested
+ typedefs. Libraries that need adaptable function objects in order to function
+ might not like mem_fn
.
+
+ Yes, if you `#define BOOST_MEM_FN_ENABLE_STDCALL. +
+
+ Non-portable extensions, in general, should default to off to prevent vendor
+ lock-in. Had BOOST_MEM_FN_ENABLE_STDCALL
+ been defined automatically, you could have accidentally taken advantage of
+ it without realizing that your code is, perhaps, no longer portable. In addition,
+ it is possible for the default calling convention to be __stdcall
,
+ in which case enabling __stdcall
+ support will result in duplicate definitions.
+
namespace boost +{ + template<class T> T *+get_pointer
(T * p); + + template<class R, class T> unspecified-1mem_fn
(R (T::*pmf) ()); + + template<class R, class T> unspecified-2mem_fn
(R (T::*pmf) () const); + + template<class R, class T> unspecified-2-1mem_fn
(R T::*pm); + + template<class R, class T, class A1> unspecified-3mem_fn
(R (T::*pmf) (A1)); + + template<class R, class T, class A1> unspecified-4mem_fn
(R (T::*pmf) (A1) const); + + template<class R, class T, class A1, class A2> unspecified-5mem_fn
(R (T::*pmf) (A1, A2)); + + template<class R, class T, class A1, class A2> unspecified-6mem_fn
(R (T::*pmf) (A1, A2) const); + + // implementation defined number of additional overloads for more arguments +} +
+ All unspecified-N types mentioned in the Synopsis are
+ CopyConstructible and Assignable.
+ Their copy constructors and assignment operators do not throw exceptions.
+ unspecified-N::result_type
is defined as the return type
+ of the member function pointer passed as an argument to mem_fn
+ (R
in the Synopsis.) unspecified-2-1::result_type
+ is defined as R
.
+
get_pointer
+template<class T> T * get_pointer(T * p) ++
p
.
+ mem_fn
+template<class R, class T> unspecified-1 mem_fn(R (T::*pmf) ()) ++
(t)
is equivalent to (t.*pmf)()
+ when t
is an l-value
+ of type T
or derived,
+ (get_pointer(t)->*pmf)()
otherwise.
+ template<class R, class T> unspecified-2 mem_fn(R (T::*pmf) () const) ++
(t)
is equivalent to (t.*pmf)()
+ when t
is of type T
[const
] or derived,
+ (get_pointer(t)->*pmf)()
otherwise.
+ template<class R, class T> unspecified-2-1 mem_fn(R T::*pm) ++
(t)
is equivalent to t.*pm
+ when t
is of type T
[const
] or derived,
+ get_pointer(t)->*pm
otherwise.
+ template<class R, class T, class A1> unspecified-3 mem_fn(R (T::*pmf) (A1)) ++
(t, a1)
is equivalent to (t.*pmf)(a1)
+ when t
is an l-value
+ of type T
or derived,
+ (get_pointer(t)->*pmf)(a1)
otherwise.
+ template<class R, class T, class A1> unspecified-4 mem_fn(R (T::*pmf) (A1) const) ++
(t, a1)
is equivalent to (t.*pmf)(a1)
+ when t
is of type T
[const
] or derived,
+ (get_pointer(t)->*pmf)(a1)
otherwise.
+ template<class R, class T, class A1, class A2> unspecified-5 mem_fn(R (T::*pmf) (A1, A2)) ++
(t, a1, a2)
is equivalent to (t.*pmf)(a1, a2)
+ when t
is an l-value
+ of type T
or derived,
+ (get_pointer(t)->*pmf)(a1, a2)
otherwise.
+ template<class R, class T, class A1, class A2> unspecified-6 mem_fn(R (T::*pmf) (A1, A2) const) ++
(t, a1, a2)
is equivalent to (t.*pmf)(a1, a2)
+ when t
is of type T
[const
] or derived,
+ (get_pointer(t)->*pmf)(a1, a2)
otherwise.
+ mem_fn.hpp
, do not include directly)
+ mem_fn.hpp
, do not include directly)
+ mem_fn.hpp
, do not include directly)
+ __fastcall
)
+ __stdcall
)
+ void
returns)
+ + This implementation supports member functions with up to eight arguments. + This is not an inherent limitation of the design, but an implementation detail. +
++ Some platforms allow several types of member functions that differ by their + calling convention (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.) +
+
+ For example, Windows API functions and COM interface member functions use
+ a calling convention known as __stdcall
.
+ Borland VCL components use __fastcall
.
+ UDK, the component model of OpenOffice.org, uses __cdecl
.
+
+ To use mem_fn
with __stdcall
member functions, #define
the macro BOOST_MEM_FN_ENABLE_STDCALL
+ before including <boost/mem_fn.hpp>
.
+
+ To use mem_fn
with __fastcall
member functions, #define
the macro BOOST_MEM_FN_ENABLE_FASTCALL
+ before including <boost/mem_fn.hpp>
.
+
+ To use mem_fn
with __cdecl
member functions, #define
the macro BOOST_MEM_FN_ENABLE_CDECL
+ before including <boost/mem_fn.hpp>
.
+
+ It is best to define these macros in the project options,
+ via -D
+ on the command line, or as the first line in the translation unit (.cpp file)
+ where mem_fn
is used.
+ Not following this rule can lead to obscure errors when a header includes
+ mem_fn.hpp
before the macro has been defined.
+
+ [Note: this is a non-portable extension. It is not part + of the interface.] +
+
+ [Note: Some compilers provide only minimal support for
+ the __stdcall
keyword.]
+
mem_fn
adapt to user-defined smart pointers
+ inspired the get_pointer
-based
+ design.
+ __stdcall
.
+ bind
+ and mem_fn
to support
+ void
returns on deficient
+ compilers.
+ __cdecl
.
+ + This documentation was ported to Quickbook by Agustín Bergé. +
+Last revised: June 06, 2015 at 16:07:47 GMT |
++ |