| # bind.hpp

## Contents

### Purpose

#### Using bind with functions and function pointers

#### Using bind with function objects

#### Using bind with member function pointers

#### 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?

#### Why doesn't bind automatically recognize nonstandard functions?

### Troubleshooting

### Interface

#### Synopsis

#### Common requirements

#### Common definitions

#### bind

### Implementation

#### Files

#### Dependencies

#### Number of Arguments

#### "__stdcall" and "pascal" Support

#### MSVC specific problems and workarounds

#### visit_each support

### Acknowledgements

## Purpose

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.

### Using bind with functions and function pointers

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

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

    std::bind2nd(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);

### Using bind with 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
    {
        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

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

### Using bind with member function pointers

Pointers to member functions are not function objects, because they do not support `operator()`. For convenience, bind accepts member function pointers as its first argument, and the behavior is as if boost::mem_fn has been used to convert the member function pointer into a function object. In other words, the expression

    bind(&X::f, args)

is equivalent to

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

where R is the return type of X::f.

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

### Using nested binds for function composition

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

    bind(f, bind(g, _1))(x);               // f(g(x))

The nested subexpressions are evaluated when the function object is called. 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 an exception to the nesting rules. A nested bind expression passed to bind as a first argument is not treated differently from any other function object:

    int x = 4;

    template<class F> void test(F f)
    {
        bind(f, 5)(x);
    }

    int g(int, int);

    int main()
    {
        test(bind(g, _1, 8));              // g(5, 8) and not g(x, 8)(5)
    }

## Examples

### Using bind with standard algorithms

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

### Using bind with Boost.Function

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

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

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.

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 const & t);

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 corresponding issue has not been resolved yet.]

## Frequently Asked Questions

### Why doesn't this compile?

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.

### 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. 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, ...)`.

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.

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

### Does bind work with COM methods?

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.

### 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 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 their default calling convention, in which case no separate support would be necessary.

## Troubleshooting

This section is still under development.

## Interface

### Synopsis

    namespace boost
    {

    // no arguments

    template<class R, class F> implementation-defined-1 bind(F f);

    template<class F> implementation-defined-1-1 bind(F f);

    template<class R> implementation-defined-2 bind(R (*f) ());

    // one argument

    template<class R, class F, class A1> implementation-defined-3 bind(F f, A1 a1);

    template<class F, class A1> implementation-defined-3-1 bind(F f, A1 a1);

    template<class R, class B1, class A1> implementation-defined-4 bind(R (*f) (B1), A1 a1);

    template<class R, class T, class A1> implementation-defined-5 bind(R (T::*f) (), A1 a1);

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

    // two arguments

    template<class R, class F, class A1, class A2> implementation-defined-7 bind(F f, A1 a1, A2 a2);

    template<class F, class A1, class A2> implementation-defined-7-1 bind(F f, A1 a1, A2 a2);

    template<class R, class B1, class B2, class A1, class A2> implementation-defined-8 bind(R (*f) (B1, B2), A1 a1, A2 a2);

    template<class R, class T, class B1, class A1, class A2> implementation-defined-9 bind(R (T::*f) (B1), A1 a1, A2 a2);

    template<class R, class T, class B1, class A1, class A2> implementation-defined-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2);

    // implementation defined number of additional overloads for more arguments

    }

    namespace
    {

    implementation-defined-placeholder-type-1 _1;

    implementation-defined-placeholder-type-2 _2;

    implementation-defined-placeholder-type-3 _3;

    // implementation defined number of additional placeholder definitions

    }

### Common requirements

All `implementation-defined-N` types returned by bind are CopyConstructible. `implementation-defined-N::result_type` is defined as the return type of `implementation-defined-N::operator()`.

All `implementation-defined-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:

- `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> implementation-defined-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> implementation-defined-1-1 bind(F f)

Effects: equivalent to `bind<typename F::result_type, F>(f);`

#### template<class R> implementation-defined-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> implementation-defined-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> implementation-defined-3-1 bind(F f, A1 a1)

Effects: equivalent to `bind<typename F::result_type, F, A1>(f, a1);`

#### template<class R, class B1, class A1> implementation-defined-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> implementation-defined-5 bind(R (T::*f) (), A1 a1)

Effects: equivalent to `bind<R>(boost::mem_fn(f), a1);`

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

Effects: equivalent to `bind<R>(boost::mem_fn(f), a1);`

#### template<class R, class F, class A1, class A2> implementation-defined-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> implementation-defined-7-1 bind(F f, A1 a1, A2 a2)

Effects: equivalent to `bind<typename F::result_type, F, A1, A2>(f, a1, a2);`

#### template<class R, class B1, class B2, class A1, class A2> implementation-defined-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> implementation-defined-9 bind(R (T::*f) (B1), A1 a1, A2 a2)

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

#### template<class R, class T, class B1, class A1, class A2> implementation-defined-10 bind(R (T::*f) (B1) const, A1 a1, A2 a2)

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

## Implementation

### Files

- boost/bind.hpp (main header)
- boost/bind/bind_cc.hpp (used by bind.hpp, do not include directly)
- boost/bind/bind_mf_cc.hpp (used by bind.hpp, do not include directly)
- boost/bind/bind_template.hpp (used by bind.hpp, do not include directly)
- libs/bind/bind_test.cpp (test)
- libs/bind/bind_as_compose.cpp (function composition example)
- libs/bind/bind_visitor.cpp (visitor example)
- libs/bind/bind_stdcall_test.cpp (test with __stdcall functions)
- libs/bind/bind_stdcall_mf_test.cpp (test with __stdcall member functions)

### Dependencies

- Boost.Config
- boost/ref.hpp
- boost/mem_fn.hpp

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

### "__stdcall" and "pascal" Support

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

### MSVC specific problems and workarounds

Microsoft Visual C++ (up to version 7.0) does not fully support the bind<R>(...) syntax required by the library when arbitrary function objects are bound. The first problem is that when boost::bind is brought into scope with an using declaration:

    using boost::bind;

the syntax above does not work. Workaround: either use the qualified name, boost::bind, or use an using directive instead:

    using namespace boost;

The second problem is that some libraries contain nested class templates named bind (ironically, such code is often an MSVC specific workaround.) Due to some quirks with the parser, such a class template breaks the bind<R>(...) syntax, even when the name bind is fully qualified. You may try to patch the library in question or contact its author/maintainer. The other option is to 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.]

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

## Acknowledgements

Earlier efforts that have influenced the library design:

- The Binder Library by Jaakko Järvi;
- The Lambda Library by Jaakko Järvi and Gary Powell (the successor to the Binder Library);
- Extensions to the 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 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.

Copyright © 2001 by Peter Dimov and Multi Media Ltd. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.