[ bind ]

The function template bind is a function object adaptor that replaces the STL std::bind1st and std::bind2nd. It enables the usage of placeholder types supposed to designate arguments value that will be supplied later to the callable wrapper.

Template function bind:

#include <tr1/functional>
using std::tr1::bind;

template <class R, class Fty, class T1, class T2, ... , class Tn>
unspecified bind(Fty fn, T1 t1, T2 t2, ..., Tn tn);

note: bind returns a callable wrapper which calls through the callable object fn provided to bind as first argument. Additional arguments to bind are supplied to the callable object.

Ordinary arguments:

ordinary arguments are supplied to the target object (forwarding):

void function()
{ ... }

struct functor : public std::unary_function<int, void>
{
    void operator()(int a) const
    { ... }
};

struct functor2 : public std::binary_function<int,int,void>
{
    void operator()(int a, int b) const
    { ... }
};

struct object 
{
    void method(int n)
    { ... }
};

...

bind(function)();

functor f;
bind(f,1)();    // f(1): 1 is supplied as argument to f

object obj;
bind(&object::method, obj, 1)();

Placeholders:

placeholders types are used to designate arguments values of the callable wrapper to be passed to the target object:

namespace std {
    namespace tr1 {
        namespace placeholders {
            extern unspecified _1;
            extern unspecified _2;
            extern unspecified _3;
            ...
        }
    }
}

using namespace std::tr1::placeholders;

functor fun;
functor2 fun2;
int a,b,c;

bind(fun,_1)(a,b);                 // call fun(a): a is supplied as argument to fun.
bind(fun,_2)(a,b);                 // call fun(b): b is supplied as argument to fun.

bind(fun2,_1,_2) (a,b);            // call fun2(a,b)
bind(fun2,_2,_1) (a,b);            // call fun2(b,a)
bind(fun2,_1, 0) (a,b,c);          // call fun2(a,0)

object obj;
bind(&object::method, obj, _1)(a); // call obj.method(a);

example: count the elements greater than zero in a STL container.

std::vector<int> abc;

abc.push_back(0);
abc.push_back(1);
abc.push_back(2);

// count the elements greater than zero
int n = std::count_if(abc.begin(), abc.end(), std::tr1::bind(std::greater<int>(), _1, 0));     // return 2  
        

Reference wrapper arguments:

Arguments to bind are passed by value:

#include <tr1/functional>

using namespace std::tr1::placeholders;
using std::tr1::bind;
using std::tr1::ref;

void increment(int &n)
{
    n++;
}

bind(increment,a)();        // does not increment a: arguments to binds are passed by value
bind(increment,_1)(a);      // does increment a!

It is possible to pass bind a reference_wrapper:

bind(increment,ref(a))();   // does increment a!

Metafunction is_placeholder / is_bind_expression:

is_placeholder metafunction is used to determine if the argument type is a placeholder and in case its value. 0 is returned if T is a non-placeholder type.

template <class T> struct is_placeholder {
    static const int value;
}

is_bind_expression metafunction is used to determine if the argument type is a bind expression. 

template <class T> struct is_bind_expression {
    static const bool value;
}


Comments