A functor from scratch that works with std bind2nd


For a functor to work with bind2nd, it usually derives from binary_function.
However, making one from scratch is not much work as illustrated in the following.

struct FunctorAdd //takes two parameters, operator() returns the sum of the two.
{
int operator()(const int & i, const int & j) const 
{ return i+j; 
}
typedef int result_type;
typedef int first_argument_type;
typedef int second_argument_type;
};
void Test_bind2nd()
{
int a[] = {0, 2, 3 };
int c = count_if ( a, a + 3, bind2nd(FunctorAdd(), 0) ); //bind2nd is a system adapter in std
//count the ones that are not 0
_ASSERT(c == 2); //this proves FunctorAdd works well with bind2nd
}
Advertisements

A minimum implementation of std bind2nd from scratch


This home-made Bind2nd, which simulates std::bind2nd, is described as following:
1. make a regular two-parameter functor and add some typedefS, which will be used by the adapter.
2. make a one-parameter functor based one the typedefS.
3. make the adapter, which returns a one-parameter functor.

struct FunctorAdd //takes two parameters, operator() returns the sum of the two.
{
	int operator()(const int & i, const int & j) const 
	{       return i+j;      
	}
	typedef int result_type; //these typedef are for adapter Bind2nd
	typedef int first_argument_type;
	typedef int second_argument_type;
};
template<typename T>
struct FunctorWithOneParameter //this is what Bind2nd transforms FunctorAdd to
{
	T mt;
	typename T::second_argument_type mr; //'typename' cannot be prelaced by 'class'
	FunctorWithOneParameter(const T& t, typename T::second_argument_type r): mt(t), mr(r) { }
	typename T::result_type operator()(typename const T::first_argument_type& l) { return mt(l, mr); }
};
template<typename T>
FunctorWithOneParameter<T> Bind2nd(const T& t, typename T::second_argument_type r) //Bind2nd is the home-made adapter
{
	return FunctorWithOneParameter<T>(t, r);
}

void TestAdapter()
{	int iBind = Bind2nd(FunctorAdd(), 3)(1); //bind by home-made Bind2nd
	_ASSERT(iBind == 4);
	int a[] = {0, 2, 3 };
	int c = count_if ( a, a + 3, Bind2nd(FunctorAdd(), 0) );//count the ones that are not 0
	_ASSERT(c == 2); //this proves Bind2nd is a successful adapter for FunctorAdd
}