From ad46d513d77e6484269d8644e706ef4e1dccd33e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 15 Oct 2002 12:45:49 +0000 Subject: [PATCH] Documented new bind(type(), f, ...) syntax. [SVN r15932] --- bind.html | 906 +++++++++++++++++++++--------------------------------- 1 file changed, 347 insertions(+), 559 deletions(-) diff --git a/bind.html b/bind.html index 4f125ee..9c7b598 100644 --- a/bind.html +++ b/bind.html @@ -4,87 +4,84 @@ Boost: bind.hpp documentation - - + +
- - - +
- c++boost.gif (8819 bytes) + c++boost.gif (8819 bytes) +

bind.hpp

  

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

-

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

-

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", "__fastcall", and - "pascal" Support

-

Using the BOOST_BIND macro

-

visit_each support

-

Acknowledgements

+

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

+

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

+

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", "__fastcall", and + "pascal" Support

+

visit_each support

+

Acknowledgements

Purpose

-

- boost::bind is a generalization of the standard functions std::bind1st +

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 @@ -93,11 +90,9 @@ standard typedefs.

Using bind with functions and function pointers

-

- Given these definitions: +

Given these definitions:

-
-int f(int a, int b)
+		
int f(int a, int b)
 {
     return a + b;
 }
@@ -107,36 +102,28 @@ 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 +

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 +

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 +

For comparison, here is the same operation expressed with the standard library primitives:

-
-std::bind2nd(std::ptr_fun(f), 5)(x);
+		
std::bind2nd(std::ptr_fun(f), 5)(x);
 
-

- bind covers the functionality of std::bind1st as well: +

bind covers the functionality of std::bind1st as well:

-
-std::bind1st(std::ptr_fun(f), 5)(x);   // f(5, x)
+		
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 +

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(f, _2, _1)(x, y);                 // f(y, x)
 
 bind(g, _1, 9, _1)(x);                 // g(x, 9, x)
 
@@ -144,41 +131,34 @@ 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, +

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 +

The arguments that bind takes are copied and held internally by the returned function object. For example, in the following code:

-
-int i = 5;
+		
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 +

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;
+		
int i = 5;
 
 bind(f, ref(i), _1);
 

Using bind with function objects

-

- bind is not limited to functions; it accepts arbitrary function objects. +

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
+		
struct F
 {
     int operator()(int a, int b) { return a - b; }
     bool operator()(long a, long b) { return a == b; }
@@ -190,49 +170,44 @@ int x = 104;
 
 bind<int>(f, _1, _1)(x);		// f(x, x), i.e. zero
 
-

- When the function object exposes a nested type named result_type, the +

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;
+		

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

[Note: the ability to omit the return type is not available on all compilers.]

Using bind with pointers to members

-

- Pointers to member functions and pointers to data members are not function +

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 + 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)
+		
bind(&X::f, args)
 
-

- is equivalent to +

is equivalent to

-
-bind<R>(mem_fn(&X::f), args)
+		
bind<R>(mem_fn(&X::f), args)
 
-

- where R is the return type of X::f (for member functions) or a +

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 - pointer, a reference, or a smart pointer to an object as its first argument; - for additional information, see the mem_fn documentation.] +

[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: +

Example:

-
-struct X
+		
struct X
 {
     bool f(int a);
 };
@@ -245,60 +220,51 @@ 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)
+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" +

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 + 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().

Using nested binds for function composition

-

- Some of the arguments passed to bind may be nested bind expressions +

Some of the arguments passed to bind may be nested bind expressions themselves:

-
-bind(f, bind(g, _1))(x);               // f(g(x))
+		
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 +

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

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, +

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);
+		
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 +

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:

-
-typedef void (*pf)(int);
+		
typedef void (*pf)(int);
 
 std::vector<pf> v;
 
@@ -315,8 +281,7 @@ std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));
 			evaluation, use protect(bind(f, ...)).

Examples

Using bind with standard algorithms

-
-class image;
+		
class image;
 
 class animation
 {
@@ -346,12 +311,11 @@ void render(image & target)
 }
 

Using bind with Boost.Function

-
-class button
+		
class button
 {
 public:
 
-    boost::function<void> onClick;
+    boost::function<void> onClick;
 };
 
 class player
@@ -371,121 +335,90 @@ void connect()
     stopButton.onClick = boost::bind(&player::stop, &thePlayer);
 }
 
-

Limitations

-

- The function objects generated by bind take their arguments by reference +

Limitations

+

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, known as the "forwarding - function problem." + is an inherent limitation of the C++ language, known as + the forwarding problem.

+

The library uses signatures of the form

-

- The library uses signatures of the form -

-
-template<class T> void f(T & t);
+		
template<class T> void f(T & t);
 
-

- to accept arguments of arbitrary types and pass them on unmodified. As noted, +

to accept arguments of arbitrary types and pass them on unmodified. As noted, this does not work with non-const r-values.

-

- An oft-proposed "solution" to this problem is to add an overload: +

An oft-proposed "solution" to this problem is to add an overload:

-
-template<class T> void f(T & t);
+		
template<class T> void f(T & t);
 template<class T> void f(T const & t);
 
-

- Unfortunately, this (a) requires providing 512 overloads for nine arguments and +

Unfortunately, this (a) requires providing 512 overloads for nine arguments and (b) does not actually work for const arguments, both l- and r-values, since the two templates produce the exact same signature and cannot be partially ordered.

-

- [Note: this is a dark corner of the language, and the +

[Note: this is a dark corner of the language, and the corresponding issue has not been resolved yet.]

Frequently Asked Questions

Why doesn't this compile?

-

- See the dedicated Troubleshooting section. -

+

See the dedicated Troubleshooting section.

Why does this compile? It should not.

-

- Probably because you used the general bind<R>(f, ...) syntax, thereby - instructing bind to not "inspect" f to detect arity and return - type errors. -

+

Probably because you used the general bind<R>(f, ...) syntax, + thereby instructing bind to not "inspect" f to detect arity and + return type errors.

What is the difference between bind(f, ...) and bind<R>(f, ...)?

-

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

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 + 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, ...). -

-

- Another important factor to consider is that compilers without partial template + 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. -

+ function pointer.

Does bind work with Windows API functions?

-

- 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_STDCALL. An + alternative is to treat the function as a generic + function object and use the bind<R>(f, ...) syntax.

Does bind work with COM methods?

-

- Yes, if you #define BOOST_MEM_FN_ENABLE_STDCALL. -

+

Yes, if you #define BOOST_MEM_FN_ENABLE_STDCALL.

Does bind work with Mac toolbox functions?

-

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

+

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.

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

+

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?

-

- Non-portable extensions, in general, should default to off to prevent vendor - lock-in. Had the appropriate macros been defined +

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

+ necessary.

Troubleshooting

Incorrect number of arguments

-

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

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);
+			where bind() is invoked:

+
int f(int, int);
 
 int main()
 {
@@ -493,12 +426,9 @@ int main()
     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
+		

A common variation of this error is to forget that member functions have an + implicit "this" argument:

+
struct X
 {
     int f(int);
 }
@@ -506,25 +436,19 @@ struct X
 int main()
 {
     boost::bind(&X::f, 1);     // error, X::f takes two arguments
-    boost::bind(&X::f, _1, 1); // OK
+    boost::bind(&X::f, _1, 1); // OK
 }
 

The function object cannot be called with the specified arguments

-

- As in normal function calls, the function object that is bound must be +

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_]);
+			on a line that looks like:

+
    return f(a[a1_], a[a2_]);
 
-

- An example of this kind of error: -

-
-int f(int);
+		

An example of this kind of error:

+
int f(int);
 
 int main()
 {
@@ -535,13 +459,10 @@ int main()
 }
 

Accessing an argument that does not exist

-

- The placeholder _N selects the argument at position N from the +

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);
+			access beyond the end of this list:

+
int f(int);
 
 int main()
 {
@@ -549,148 +470,119 @@ int main()
     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_]);
+		

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). -

+

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).

Inappropriate use of bind(f, ...)

-

- 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, +

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

+ for function objects.

Inappropriate use of bind<R>(f, ...)

-

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

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

+ functions and member function pointers.

Binding a nonstandard function

-

- By default, the bind(f, a1, a2, ..., aN) form recognizes +

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

On some platforms, extern "C" functions, like std::strcmp, are not recognized by the short form of bind.

-

- See also "__stdcall" and "pascal" Support.

+

See also "__stdcall" and "pascal" Support.

const in signatures

-

- Some compilers, including MSVC 6.0 and Borland C++ 5.5.1, have problems with - the top-level const in function signatures: +

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 f(int const);
 
 int main()
 {
     boost::bind(f, 1);     // error
 }
 
-

- Workaround: remove the const qualifier from the argument. +

Workaround: remove the const qualifier from the argument.

MSVC specific: using boost::bind;

-

- On MSVC (up to version 7.0), when boost::bind is brought into scope with +

On MSVC (up to version 7.0), when boost::bind is brought into scope with an using declaration:

-
-using boost::bind;
+		
using boost::bind;
 
-

- the syntax bind<R>(...) does not work. Workaround: either use the - qualified name, boost::bind, or use an using directive instead: +

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;
+		
using namespace boost;
 

MSVC specific: class templates shadow function templates

-

- On MSVC (up to version 7.0), a nested class template named bind will - shadow the function template boost::bind, breaking the bind<R>(...) - syntax. Unfortunately, some libraries contain nested class templates named bind - (ironically, such code is often an MSVC specific workaround.) You may try to - patch the library in question or contact its author/maintainer. The other - option is use the BOOST_BIND macro to rename bind. -

+

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 specific: ... in signatures treated as type

-

- MSVC (up to version 7.0) treats the ellipsis in a variable argument function +

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);
+		
    bind(printf, "%s\n", _1);
 
-

- and will reject the correct version: +

and will reject the correct version:

-
-    bind<int>(printf, "%s\n", _1);
+		
    bind<int>(printf, "%s\n", _1);
 

Interface

Synopsis

-
-namespace boost
+		
namespace boost
 {
 
 // no arguments
 
-template<class R, class F> unspecified-1 bind(F f);
+template<class R, class F> unspecified-1 bind(F f);
 
-template<class F> unspecified-1-1 bind(F f);
+template<class F> unspecified-1-1 bind(F f);
 
-template<class R> unspecified-2 bind(R (*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 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 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 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-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 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 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 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 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 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-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);
+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
 
@@ -699,33 +591,27 @@ template<class R, class T, class B1, class A1, class A2> unspecified-10
 namespace
 {
 
-unspecified-placeholder-type-1 _1;
+unspecified-placeholder-type-1 _1;
 
-unspecified-placeholder-type-2 _2;
+unspecified-placeholder-type-2 _2;
 
-unspecified-placeholder-type-3 _3;
+unspecified-placeholder-type-3 _3;
 
 // implementation defined number of additional placeholder definitions
 
 }
 

Common requirements

-

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

+

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.

Common definitions

-

- The function µ(x, v1, v2, ..., vm), where m is - a nonnegative integer, is defined as: -

+

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> + x.get(), when x is of type boost::reference_wrapper<T> for some type T;
  • vk, when x @@ -734,179 +620,129 @@ namespace x(v1, v2, ..., vm) when x is (a copy of) a function object returned by bind;
  • - x otherwise.
  • -
+ x otherwise.

bind

template<class R, class F> unspecified-1 bind(F f)

-

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

-

- Throws: Nothing unless the copy constructor of F throws an - exception. -

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

+

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

+

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, +

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

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

+

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, +

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

+ 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)

-

- Effects: Equivalent to bind<R>(boost::mem_fn(f), - a1); -

+

Effects: Equivalent to bind<R>(boost::mem_fn(f), + a1);

template<class R, class T, class A1> unspecified-6 bind(R (T::*f) () const, A1 a1)

-

- Effects: Equivalent to bind<R>(boost::mem_fn(f), - a1); -

+

Effects: Equivalent to bind<R>(boost::mem_fn(f), + a1);

template<class R, class T, class A1> unspecified-6-1 bind(R T::*f, A1 a1)

-

- Effects: Equivalent to bind<R const &>(boost::mem_fn(f), - a1); -

+

Effects: Equivalent to bind<R const &>(boost::mem_fn(f), + 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, +

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

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

+

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, +

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

+ 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)

-

- Effects: Equivalent to bind<R>(boost::mem_fn(f), - a1, a2); -

+

Effects: Equivalent to 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)

-

- Effects: Equivalent to bind<R>(boost::mem_fn(f), - a1, a2); -

+

Effects: Equivalent to bind<R>(boost::mem_fn(f), + a1, a2);

Additional overloads

-

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

+

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

Implementation

Files

+ libs/bind/bind_fastcall_mf_test.cpp (test + with __fastcall member functions)

Dependencies

Number of Arguments

-

- This implementation supports function objects with up to nine arguments. This - is an implementation detail, not an inherent limitation of the design. -

+

This implementation supports function objects with up to nine arguments. This is + an implementation detail, not an inherent limitation of the design.

"__stdcall", "__fastcall", and "pascal" Support

-

- Some platforms allow several types of (member) functions that differ by their calling +

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

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

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

-

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

-

Using the BOOST_BIND macro

-

- A bug in MSVC (up to version 7.0) causes boost::bind - to be incompatible with libraries that contain nested class templates named bind. - To work around this problem, #define the macro BOOST_BIND to - something other than bind (before the inclusion of <boost/bind.hpp>) - and use this identifier throughout your code wherever you'd normally use bind. -

-

- [Note: BOOST_BIND is not a general renaming mechanism. It is not part of the - interface, and is not guaranteed to work on other compilers, or persist between - library versions. In short, don't use it unless you absolutely have to.] -

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

+

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

visit_each support

-

- Function objects returned by bind support the experimental and - undocumented, as of yet, visit_each enumeration interface. -

-

- See bind_visitor.cpp for an example. -

+

Function objects returned by bind support the experimental and + undocumented, as of yet, visit_each enumeration interface.

+

See bind_visitor.cpp for an example.

Acknowledgements

-

- Earlier efforts that have influenced the library design: -

+

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 + STL by Petter Urkedal. +

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 +

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 fixed a MSVC-specific conflict between bind and the + iterator adaptors library.

-

- Dave Abrahams modified bind and mem_fn to support void returns on +

Dave Abrahams modified bind and mem_fn to support void returns on deficient compilers.

-

- Mac Murrett contributed the "pascal" support enabled by +

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.