1. 程式人生 > >boost::bind繫結成員變數,函式書巢狀

boost::bind繫結成員變數,函式書巢狀

</pre><pre name="code" class="cpp"><span style="color:#333333;">#ifndef BOOST_BIND_BIND_HPP_INCLUDED__Mybind
#define BOOST_BIND_BIND_HPP_INCLUDED__Mybind

#include <iostream>
using namespace std;
namespace boost {
template<class T> struct is_placeholder {
	enum _vt {
		value = 0
	};
};
template<int I> struct arg {
	arg() {
	}
};
template<class T>
struct type {
};
namespace _bi // implementation details
{

template<class A1> struct storage1 {
	explicit storage1(A1 a1) :
			a1_(a1) {
		cout<<"storage1  storage1(A1 a1)"<<endl;
	}
	A1 a1_;
};
template<int I> struct storage1<boost::arg<I> > {
	explicit storage1(boost::arg<I>) {
		cout<<"storage1  storage1(boost::arg<I>)"<<endl;
	}
	static boost::arg<I> a1_() {
		return boost::arg<I>();
	}

};

template<int I> struct storage1<boost::arg<I> (*)()> {
	explicit storage1(boost::arg<I> (*)()) {
		cout<<"storage1  storage1(boost::arg<I> (*)())"<<endl;
	}
	static boost::arg<I> a1_() {
		return boost::arg<I>();
	}
};

// 2

template<class A1, class A2> struct storage2: public storage1<A1> {
	typedef storage1<A1> inherited;
	storage2(A1 a1, A2 a2) :
			storage1<A1>(a1), a2_(a2) {
		cout<<"storage2  storage2(A1 a1, A2 a2)"<<endl;
	}
	A2 a2_;
};

template<class A1, int I> struct storage2<A1, boost::arg<I> > : public storage1<
		A1> {
	typedef storage1<A1> inherited;
	storage2(A1 a1, boost::arg<I>) :
			storage1<A1>(a1) {
		cout<<"storage2  storage2(A1 a1, boost::arg<I>)"<<endl;
	}
	//boost::arg<I> a2_;

	static boost::arg<I> a2_() {
		return boost::arg<I>();
	}

};

template<class A1, int I> struct storage2<A1, boost::arg<I> (*)()> : public storage1<
		A1> {
	typedef storage1<A1> inherited;
	storage2(A1 a1, boost::arg<I> (*)()) :
			storage1<A1>(a1) {
		cout<<"storage2  storage2(A1 a1, boost::arg<I> (*)())"<<endl;
	}
	static boost::arg<I> a2_() {
		return boost::arg<I>();
	}
};

// result_traits
template<class R, class F> struct result_traits {
	typedef R type;
};
struct unspecified {
};
template<class F> struct result_traits<unspecified, F> {
	typedef typename F::result_type type;
};
// value
template<class T> class value {
public:
	value(T const & t) :
			t_(t) {
	}
	T & get() {
		return t_;
	}
private:
	T t_;
};
// type
template<class T> class type {
};
// unwrap
template<class F> struct unwrapper {
	static inline F & unwrap(F & f, long) {
		return f;
	}
};
// listN
class list0 {
public:
	list0() {
	}
	template<class T> T & operator[](_bi::value<T> & v) const {
		cout << "list0  T & operator[](_bi::value<T> & v)" << endl;
		return v.get();
	}
	template<class R, class F, class A> R operator()(type<R>, F & f, A &,
			long) {
		cout << "list0  R operator()(type<R>, F & f, A &, long)" << endl;
		return unwrapper<F>::unwrap(f, 0)();
	}
	template<class F, class A> void operator()(type<void>, F & f, A &, int) {
		cout << "list0  void operator()(type<void>, F & f, A &, int)" << endl;
		unwrapper<F>::unwrap(f, 0)();
	}
};

template<class A1> class list1: private storage1<A1> {
private:
	typedef storage1<A1> base_type;
public:
	explicit list1(A1 a1) :
			base_type(a1) {
	}
	A1 operator[](boost::arg<1>) const {
		return base_type::a1_;
	}
	A1 operator[](boost::arg<1> (*)()) const {
		return base_type::a1_;
	}
	template<class T> T & operator[](_bi::value<T> & v) const {
		return v.get();
	}
</span><span style="color:#ff6666;">	//template<class R, class F, class L> typename result_traits<R, F>::type operator[] (_bi::bind_t<R, F, L> & b) const { return b.eval(*this); } 這裡實現函式巢狀,沒有編譯</span><span style="color:#333333;">
	template<class R, class F, class A> R operator()(type<R>, F & f, A & a,
			long) {
		return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]);
	}
//	template<class F, class A> void operator()(type<void>, F & f, A & a, int) {
//		unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]);
//	}
};

template<class A1, class A2> class list2: private storage2<A1, A2> {
private:
	typedef storage2<A1, A2> base_type;
public:
	list2(A1 a1, A2 a2) :
			base_type(a1, a2) {
	}
	A1 operator[](boost::arg<1> ) const {
		cout << "list2  A1 operator[](boost::arg<1>)" << endl;
		return base_type::a1_;
	}
	A2 operator[](boost::arg<2> ) const {
		cout << "list2  A1 operator[](boost::arg<2>)" << endl;
		return base_type::a2_;
	}
	
	A1 operator[](boost::arg<1> (*)()) const {
		cout << "list2  A1 operator[](boost::arg<1> (*)())" << endl;
		return base_type::a1_;
	}
	A2 operator[](boost::arg<2> (*)()) const {
		cout << "list2  A1 operator[](boost::arg<2> (*)())" << endl;
		return base_type::a2_;
	}
	
	template<class T> T & operator[](_bi::value<T> & v) const {
		cout << "T & operator[](_bi::value<T> & v)" << endl;
		return v.get();
	}
	template<class R, class F, class A> R operator()(type<R>, F & f, A & a,
			long) {
		return f(a[base_type::a1_], a[base_type::a2_]);

	}

};
// bind_t
template<class R, class F, class L> class bind_t {
public:
	void test(){
		cout << "haha test" << endl;
	}
	typedef bind_t this_type;
	bind_t(F f, L const & l) :
			f_(f), l_(l) {
	}
	typedef typename result_traits<R, F>::type result_type;
	result_type operator()() {
		cout << "bind_t::result_type operator()()" << endl;
		list0 a;
		return l_(type<result_type>(), f_, a, 0);
	}
	template<class A1> result_type operator()(A1 & a1) {
		list1<A1 &> a(a1);
		return l_(type<result_type>(), f_, a, 0);
	}	
	template<class A1, class A2> result_type operator()(A1 & a1, A2 & a2) {
		cout << "bind_t::operator(1)" << endl;
		list2<A1 &, A2 &> a(a1, a2);
		return l_(type<result_type>(), f_, a, 0);
	}
</span><span style="color:#ff6666;">/*
	template<class A> result_type eval(A & a)
	{
		return l_(type<result_type>(), f_, a, 0);
	}
*/</span><span style="color:#333333;">

private:
	F f_;
	L l_;
};

template<class T, int I> struct add_value_2 {
	typedef boost::arg<I> type;
};

template<class T> struct add_value_2<T, 0> {
	typedef _bi::value<T> type;
};
template<class T> struct add_value {
	typedef typename add_value_2<T, boost::is_placeholder<T>::value>::type type;
};
template<class T> struct add_value<value<T> > {
	typedef _bi::value<T> type;
};
template<int I> struct add_value<arg<I> > {
	typedef boost::arg<I> type;
};
//template<int I> struct add_value<arg<I> (*)()> {
//	typedef boost::arg<I> (*type)();
//};
template<class R, class F, class L> struct add_value<bind_t<R, F, L> > {
	typedef bind_t<R, F, L> type;
};
// list_av_N
template<class A1> struct list_av_1 {
	typedef typename add_value<A1>::type B1;
	typedef list1<B1> type;
};
template<class A1, class A2> struct list_av_2 {
	typedef typename add_value<A1>::type B1;
	typedef typename add_value<A2>::type B2;
	typedef list2<B1, B2> type;
};
} // namespace _bi

// function pointers
template<class R>
_bi::bind_t<R, R (*)(), _bi::list0> bind2(R (*f)()) {
	typedef R (*F)();
	typedef _bi::list0 list_type;
	return _bi::bind_t<R, F, list_type>(f, list_type());
}
template<class R, class B1, class A1>
_bi::bind_t<R, R (*)(B1), typename _bi::list_av_1<A1>::type> bind2(R (*f)(B1),
		A1 a1) {
	typedef R (*F)(B1);
	typedef typename _bi::list_av_1<A1>::type list_type;
	return _bi::bind_t<R, F, list_type>(f, list_type(a1));
}
template<class R, class B1, class B2, class A1, class A2>
_bi::bind_t<R, R (*)(B1, B2), typename _bi::list_av_2<A1, A2>::type> bind2(
		R (*f)(B1, B2), A1 a1, A2 a2) {
	typedef R (*F)(B1, B2);
	typedef typename _bi::list_av_2<A1, A2>::type list_type;
	return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2));
}

template<class R, class T, class A1 > 
	class mf1
{
public:

    typedef R result_type;
    typedef T * first_argument_type;
    typedef A1 second_argument_type;

private:
    
    typedef R (T::*F)(A1);
    F f_;
public:
    
    explicit mf1(F f): f_(f) {}

    R operator()(T & p, A1 a1) 
    {
     cout << "mf1::operator(1)" << endl;
        (p.*f_)(a1);
    }
	  R operator()(T * p, A1 a1) 
    {
     cout << "mf1::operator(2)" << endl;
        (p->*f_)(a1);
    }
	  R operator()(T const & p, A1 a1) 
    {
     cout << "mf1::operator(3)" << endl;
        (p.*f_)(a1);
    }
};

template<class R, class T,  class B1,class A1, class A2>
_bi::bind_t<R, mf1<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
bind2(	R (T::*f)(B1), A1 a1, A2 a2) 
{
	typedef mf1<R, T, B1> F;
	typedef typename _bi::list_av_2<A1, A2>::type list_type;
	return _bi::bind_t<R, F, list_type>( F(f), list_type(a1, a2));
}

template<class R, class T> class dm
{
public:

    typedef R const & result_type;
    typedef T const * argument_type;

private:
    
    typedef R (T::*F);
    F f_;

public:
    
    explicit dm(F f): f_(f) {}

    R & operator()(T * p) const
    {
        return (p->*f_);
    }

    R const & operator()(T const * p) const
    {
        return (p->*f_);
    }

    template<class U> R const & operator()(U const & u) const
    {
        return call(u, &u);
    }


    R & operator()(T & t) const
    {
        return (t.*f_);
    }

    R const & operator()(T const & t) const
    {
        return (t.*f_);
    }
};


template<class R, class T, class A1>
_bi::bind_t< R, dm<R, T>, typename _bi::list_av_1<A1>::type >
    bind2(R T::*f, A1 a1)
{
    typedef dm<R, T> F;
    typedef typename _bi::list_av_1<A1>::type list_type;
    return _bi::bind_t<R, F, list_type>( F(f), list_type(a1) );
}



} // namespace boost

namespace {
boost::arg<1> _1;
boost::arg<2> _2;
}
template <typename R,typename T, typename Arg>
class simple_bind_t {
  typedef R (T::*fn)(Arg);
  fn fn_;
  T t_;
public:
  simple_bind_t(fn f,const T& t):fn_(f),t_(t) {}

  R operator()(Arg& a) {
    return (t_.*fn_)(a);
  }
};
template <typename R, typename T, typename Arg>
simple_bind_t<R,T,Arg> simple_bind(
  R (T::*fn)(Arg),
  const T& t,
  const int&) {
  return simple_bind_t<R,T,Arg>(fn,t);
}
#endif // #ifndef BOOST_BIND_BIND_HPP_INCLUDED__Mybind
</span>
測試main函式:
#include <iostream>
#include "bind.h"
using namespace std;
void tow_arguments(int i1, int i2) {
	std::cout <<"i1:"<< i1<<"\n" <<"i2:"<< i2 << '\n';
}

class Test {
public:  
	Test():init(123){}
	void do_stuff(int* i) 
	{    
		std::cout <<"1do_stuff hahahahaha:"<<"\n" ;
	}
	void do_stuff(int* i) const
	{    
		std::cout <<"2do_stuff hahahahaha:"<<"\n" ;
	}
	int init;
};
void testClass(Test t, int i){
	cout<<"testClass,Test,int"<<endl;
}
int main() {
	int i1 = 1, i2 = 2;
	Test t;
	Test* p = &t;
	int* i = &i1;
	(boost::bind2(&tow_arguments, 123, _1))(i1);
	std::cout <<"&Test::init: "<<(boost::bind2(&Test::init,p))()<<std::endl;
	(boost::bind2(&Test::do_stuff,_1, _2))(p,i);

	//(boost::bind2(&Test::do_stuff,t, _1))(i1);
	/*
	(boost::bind2(&tow_arguments, _1, _2))(i1, i2);
	(boost::bind2(&tow_arguments, _2, _1))(i1, i2);
	(boost::bind2(&tow_arguments, _1, _1))(i1, i2);

	(boost::bind2(&tow_arguments, 222, 666))(i1, i2);

	Test t;
	(boost::bind2(&testClass, _1, 666))(t, i2);
	(boost::bind2(&testClass, _1, 666))(t);
	(boost::bind2(&testClass, t, 666))();
	*/
}