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 @@ + + + +Chapter 1. Boost.Bind + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+
+
+

+Chapter 1. Boost.Bind

+
+
+
+

+ Distributed under the Boost + Software License, Version 1.0. +

+
+
+
+

Table of Contents

+
+
Purpose
+
+
Using + bind with functions and function pointers
+
Using bind with function + objects
+
Using + bind with pointers to members
+
Using + nested binds for function composition
+
Overloaded + operators (new in Boost 1.33)
+
+
Examples
+
+
Using + bind with standard algorithms
+
Using bind + with Boost.Function
+
+
Limitations
+
Frequently Asked Questions
+
+
Why doesn't this compile?
+
Why does this + compile? It should not.
+
What is the difference between bind(f, ...) and + bind<R>(f, ...)?
+
Does bind + work with Windows API functions?
+
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
+
+
Incorrect + number of arguments
+
The + function object cannot be called with the specified arguments
+
Accessing + an argument that does not exist
+
Inappropriate + use of bind(f, ...)
+
Inappropriate + use of bind<R>(f, ...)
+
Binding + a nonstandard function
+
Binding + an overloaded function
+
Modeling + STL function object concepts
+
const in signatures
+
MSVC + specific: using boost::bind;
+
MSVC + specific: class templates shadow function templates
+
MSVC + specific: ... in signatures treated + as type
+
+
Interface
+
+
Synopsis
+
Common requirements
+
Common definitions
+
bind
+
Additional overloads
+
+
Implementation
+
+
Files
+
Dependencies
+
Number of Arguments
+
__stdcall, + __cdecl, __fastcall, + and pascal Support
+
visit_each support
+
+
Acknowledgements
+
+
+
+ +

+ 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_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-1 bind(F f);
+
+template<class R> unspecified-2 bind(R (*f) ());
+
+// one argument
+
+template<class R, class F, class A1> unspecified-3 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> unspecified-4 bind(R (*f) (B1), A1 a1);
+
+template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), 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> unspecified-7 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> unspecified-8 bind(R (*f) (B1, B2), 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> unspecified-10 bind(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)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(), + implicitly converted to R. +
  • +
  • + Throws: Nothing unless the copy constructor of + F throws an exception. +
  • +
+
template<class F> unspecified-1-1 bind(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. +
  • +
+
template<class R> unspecified-2 bind(R (*f) ())
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(). +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class F, class A1> unspecified-3 bind(F f, A1 a1)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(μ(a1, v1, v2, ..., vm)), + implicitly converted to R. +
  • +
  • + Throws: Nothing unless the copy constructors of + F or A1 + throw an exception. +
  • +
+
template<class F, class A1> unspecified-3-1 bind(F f, A1 a1)
+
+
    +
  • + 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. +
  • +
+
template<class R, class B1, class A1> unspecified-4 bind(R (*f) (B1), A1 a1)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(μ(a1, v1, v2, ..., vm)). +
  • +
  • + Throws: Nothing unless the copy constructor of + A1 throws an exception. +
  • +
+
template<class R, class T, class A1> unspecified-5 bind(R (T::*f) (), 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)
+
+
+
template<class R, class F, class A1, class A2> unspecified-7 bind(F f, A1 a1, A2 a2)
+
+
    +
  • + 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. +
  • +
  • + Throws: Nothing unless the copy constructors of + F, A1 + or A2 throw an exception. +
  • +
+
template<class F, class A1, class A2> unspecified-7-1 bind(F f, A1 a1, A2 a2)
+
+
    +
  • + 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. +
  • +
+
template<class R, class B1, class B2, class A1, class A2> unspecified-8 bind(R (*f) (B1, B2), A1 a1, A2 a2)
+
+
    +
  • + Returns: A function object λ such that the + expression λ(v1, v2, ..., vm) + is equivalent to f(μ(a1, v1, v2, ..., vm), μ(a2, v1, v2, ..., vm)). +
  • +
  • + Throws: Nothing unless the copy constructors of + 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)
+
+
+
template<class R, class T, class B1, class A1, class A2> unspecified-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2)
+
+
+
+
+ +

+ Implementations are allowed to provide additional bind + overloads in order to support more arguments or different function pointer + variations. +

+
+
+
+ +
+

+Files +

+
+
+ +
+ +

+ 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

+
+
+ + diff --git a/doc/html/mem_fn.html b/doc/html/mem_fn.html new file mode 100644 index 0000000..486d55e --- /dev/null +++ b/doc/html/mem_fn.html @@ -0,0 +1,552 @@ + + + +Chapter 1. Boost.Member Function + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+
+
+

+Chapter 1. Boost.Member Function

+
+
+
+

+ Distributed under the Boost + Software License, Version 1.0. +

+
+
+
+

Table of Contents

+
+
Purpose
+
Frequently Asked Questions
+
+
Can mem_fn be used instead of the standard std::mem_fun[_ref] + adaptors?
+
Should I + replace every occurence of std::mem_fun[_ref] + with mem_fn in my existing + code?
+
Does mem_fn work with COM methods?
+
Why isn't + BOOST_MEM_FN_ENABLE_STDCALL + defined automatically?
+
+
Interface
+
+
Synopsis
+
Common requirements
+
get_pointer
+
mem_fn
+
+
Implementation
+
+
Files
+
Dependencies
+
Number of + Arguments
+
__stdcall, + __cdecl, and __fastcall Support
+
+
Acknowledgements
+
+
+
+ +

+ 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) ());
+
+
  • + Effects: Equivalent to 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. +

+
+ +
+ +

+ 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-1 mem_fn(R (T::*pmf) ());
+
+    template<class R, class T> unspecified-2 mem_fn(R (T::*pmf) () const);
+
+    template<class R, class T> unspecified-2-1 mem_fn(R T::*pm);
+
+    template<class R, class T, class A1> unspecified-3 mem_fn(R (T::*pmf) (A1));
+
+    template<class R, class T, class A1> unspecified-4 mem_fn(R (T::*pmf) (A1) const);
+
+    template<class R, class T, class A1, class A2> unspecified-5 mem_fn(R (T::*pmf) (A1, A2));
+
+    template<class R, class T, class A1, class A2> unspecified-6 mem_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. +

+
+
+ +
template<class T> T * get_pointer(T * p)
+
+
    +
  • + Returns: p. +
  • +
  • + Throws: Nothing. +
  • +
+
+
+

+mem_fn +

+
template<class R, class T> unspecified-1 mem_fn(R (T::*pmf) ())
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t) is equivalent to (t.*pmf)() + when t is an l-value + of type T or derived, + (get_pointer(t)->*pmf)() otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T> unspecified-2 mem_fn(R (T::*pmf) () const)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t) is equivalent to (t.*pmf)() + when t is of type T [const] or derived, + (get_pointer(t)->*pmf)() otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T> unspecified-2-1 mem_fn(R T::*pm)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t) is equivalent to t.*pm + when t is of type T [const] or derived, + get_pointer(t)->*pm otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1> unspecified-3 mem_fn(R (T::*pmf) (A1))
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(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. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1> unspecified-4 mem_fn(R (T::*pmf) (A1) const)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(t, a1) is equivalent to (t.*pmf)(a1) + when t is of type T [const] or derived, + (get_pointer(t)->*pmf)(a1) otherwise. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1, class A2> unspecified-5 mem_fn(R (T::*pmf) (A1, A2))
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(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. +
  • +
  • + Throws: Nothing. +
  • +
+
template<class R, class T, class A1, class A2> unspecified-6 mem_fn(R (T::*pmf) (A1, A2) const)
+
+
    +
  • + Returns: a function object ϝ such that the + expression ϝ(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. +
  • +
  • + Throws: Nothing. +
  • +
+
+
+
+ +
+

+Files +

+
+
+ +
+ +

+ 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.] +

+
+
+
+ +
    +
  • + Rene Jager's initial suggestion of using traits classes to make mem_fn adapt to user-defined smart pointers + inspired the get_pointer-based + design. +
  • +
  • + Numerous improvements were suggested during the formal review period by + Richard Crossley, Jens Maurer, Ed Brey, and others. Review manager was + Darin Adler. +
  • +
  • + Steve Anichini pointed out that COM interfaces use __stdcall. +
  • +
  • + Dave Abrahams modified bind + and mem_fn to support + void returns on deficient + compilers. +
  • +
  • + Daniel Boelzle pointed out that UDK uses __cdecl. +
  • +
+

+ This documentation was ported to Quickbook by Agustín Bergé. +

+
+
+ + + +

Last revised: June 06, 2015 at 16:07:47 GMT

+
+
+ +