boost::bind繫結成員變數,函式書巢狀
阿新 • • 發佈:2019-01-25
測試main函式:</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>
#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))(); */ }