The bind library is a new library voted into the first Library Technical Report. As such, it is placed in namespace std::tr1. It is not standard, but is considered "interesting" by the C++ committee. It may become standardized in the future. This is a generalization of the existing std::bind1st and std::bind2nd functions.
The bind library consists of a series of overloaded template functions which when called will return an implementation defined function object that can then be evaluated. The purpose of bind is to adapt one function to another expected signature, or to combine simpler functions into a more complex functor. It is found in the new header <bind>. This implementation supports functions with up to 10 arguments.
namespace std { namespace tr1 { // 0 argument functors template <class F> // details bind(F f); template <class R, class F> // details bind(F f); template <class R> // details bind(R (*f)()); // 1 argument functors template <class F, class A1> // details bind(F f, A1 a1); template <class R, class F, class A1> // details bind(F f, A1 a1) template <class R, class B1, class A1> // details bind(R (*f)(B1), A1 a1); template <class R, class T, class A1> // details bind(R (T::*f)(), A1 a1); template <class R, class T, class A1> // details bind(R (T::*f)() const, A1 a1); template <class R, class T, class A1> // details bind(R T::*f, A1 a1); // 2 argument functors template <class F, class A1, class A2> // details bind(F f, A1 a1, A2 a2); template <class R, class F, class A1, class A2> // details bind(F f, A1 a1, A2 a2); template <class R, class B1, class B2, class A1, class A2> // details bind(R (*f)(B1, B2), A1 a1, A2 a2); template <class R, class T, class B1, class A1, class A2> // details bind(R (T::*f)(B1), A1 a1, A2 a2); template <class R, class T, class B1, class A1, class A2> // details bind(R (T::*f)(B1) const, A1 a1, A2 a2); ... // 9 argument functors template <class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> // details bind(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9); template <class R, class F, class A1, class A2, class A3, class A4, class A5,class A6, class A7, class A8, class A9> // details bind(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9); template <class R, class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, class B9, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> // details bind(R (*f)(B1, B2, B3, B4, B5, B6, B7, B8, B9), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9); template <class R, class T, class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> // details bind(R (T::*f)(B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5,A6 a6, A7 a7, A8 a8, A9 a9); template <class R, class T, class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> // details bind(R (T::*f)(B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9); } } // std::tr1
There are bind functions that accept a function-like object as the first argument, and then from 0 to 9 arguments. The return type of the functor can be explicitly supplied as the first template argument, or not. When not supplied, it is deduced. If the functor is a function pointer or member pointer, the return type is deduced from that signature. If the functor is a class with a nested type called result_type, the return type is deduced as F::result_type.
If the functor is a member pointer, then the first argument to the resulting functor must be a reference, pointer or smart pointer to an object containing the pointed to member. That first argument must be supplied to bind either explicitly, or implicitly as another bind expression, or a placeholder (examples will follow).
The bind overloads taking a functor with no arguments and do not accept member pointers, as member pointer functors must have at least one argument for the reference or pointer to the object.
The bind overloads taking from 1 thru 9 arguments include overloads for a function-like class, function pointers, and member function pointers.
The bind overloads taking a single argument (in addition to the functor) include an overload for taking a pointer to member data. Thus you can create a functor out of a pointer to pair<T1, T2>::first (for example).
#include <vector> #include <functional> #include <algorithm> #include <numeric> #include <iterator> #include <iostream> int main() { using namespace std; vector<int> v(10, 1); partial_sum(v.begin(), v.end(), v.begin()); random_shuffle(v.begin(), v.end()); ostream_iterator<int> out(cout, " "); copy(v.begin(), v.end(), out); cout << `\n'; vector<int>::iterator i = partition(v.begin(), v.end(), bind2nd(less<int>(), 5)); copy(v.begin(), i, out); cout << `\n'; }
This should print out something similar to:
6 3 5 7 10 1 9 8 4 2
2 3 4 1
As stated in the introduction, bind is a generalization of bind1st and bind2nd. To transform the above example to use bind:
vector<int>::iterator i = partition(v.begin(), v.end(), bind2nd(less<int>(), 5));
with:
vector<int>::iterator i = partition(v.begin(), v.end(), bind(less<int>(), _1, 5));
Obviously bind is not a big win over bind2nd in this example. This example is meant to introduce bind by comparing it with the presumably well known std::bind2nd. Further examples will show how bind goes beyond the limitations of bind1st and bind2nd.
The #include <bind> is needed to bring std::tr1::bind into scope. As bind is a library technical report item, it lives in namespace std::tr1 instead of in namespace std.
The "_1" notation is new. The _1 is called a placeholder, it's full name is std::tr1::placeholders::_1. You can just say using namespace std::tr1::placeholders; to bring just the placeholders into scope without bringing everything else into scope. The _1 is a signal to the functor returned from bind to substitute the first argument used when calling the functor object into the place indicated by the position of the _1. That is:
bind1st(f, x);
is equivalent to:
bind(f, x, _1);
Both functions return a unary functor F such that F(y) calls f(x, y). In the bind example, _1 is the placeholder for y that the client will supply to F.
You can also turn f(x, y) into a function that takes no arguments by simply not using any placeholders:
bind(f, x, y); // -> F() calls f(x, y)
You can also use _1 more than once:
bind(f, _1, _1); // -> F(y) calls f(y, y)
Additionally there are more placeholders: _1, _2, _3, ... _9. You can use these placeholders to simply reorder the arguments to a function:
bind(f, _2, _1); // -> F(x, y) calls f(y, x)
And you can instruct bind to ignore parameters:
bind(f, _2, x); // -> F(y, z) calls f(z, x), y is ignored
And of course bind can handle functions (f) with a number of arguments ranging from 0 to 9. You must ensure that for every parameter of f there is a matching argument in the bind expression. Except that when f is a member function pointer, then there must be an additional argument in the bind expression, as the first argument represents the object (or a pointer to the object).