boost::bind 绑定成员函数

根据原博客:http://blog.csdn.net/hengyunabc/article/details/7773250 添加成员函数绑定功能



#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();
}
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_]);
// return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
}
// template<class F, class A> void operator()(type<void>, F & f, A & a, int) {
// unwrapper<F>::unwrap(f, 0)(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);
}
/*
    template<class A1, class A2> result_type operator()(A1 & a1, A2 & a2) const
    {
    cout << "bind_t::operator(2)" << endl;
        list2<A1 &, A2 &> a(a1, a2);
        return l_(type<result_type>(), f_, a, 0);
    }


    template<class A1, class A2> result_type operator()(A1 const & a1, A2 & a2)
    {
    cout << "bind_t::operator(3)" << endl;
        list2<A1 const &, A2 &> a(a1, a2);
        return l_(type<result_type>(), f_, a, 0);
    }


    template<class A1, class A2> result_type operator()(A1 const & a1, A2 & a2) const
    {
    cout << "bind_t::operator(4)" << endl;
        list2<A1 const &, A2 &> a(a1, a2);
        return l_(type<result_type>(), f_, a, 0);
    }




    template<class A1, class A2> result_type operator()(A1 & a1, A2 const & a2)
    {
    cout << "bind_t::operator(5)" << endl;
        list2<A1 &, A2 const &> a(a1, a2);
        return l_(type<result_type>(), f_, a, 0);
    }


    template<class A1, class A2> result_type operator()(A1 & a1, A2 const & a2) const
    {
    cout << "bind_t::operator(6)" << endl;
        list2<A1 &, A2 const &> a(a1, a2);
        return l_(type<result_type>(), f_, a, 0);
    }


    template<class A1, class A2> result_type operator()(A1 const & a1, A2 const & a2)
    {
    cout << "bind_t::operator(7)" << endl;
        list2<A1 const &, A2 const &> a(a1, a2);
        return l_(type<result_type>(), f_, a, 0);
    }


    template<class A1, class A2> result_type operator()(A1 const & a1, A2 const & a2) const
    {
    cout << "bind_t::operator(8)" << endl;
        list2<A1 const &, A2 const &> a(a1, a2);
        return l_(type<result_type>(), f_, a, 0);
    }
*/
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));
}
} // 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

实验代码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:  void do_stuff(int* i) 
{    
std::cout <<"1do_stuff hahahahaha:"<<"\n" ;
}
public:  void do_stuff(int* i) const
{    
std::cout <<"2do_stuff hahahahaha:"<<"\n" ;
}
};
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);
//boost::_bi::storage2<int,1> b;
//(boost::bind2(&Test::do_stuff, _1, _2)).test();//(&t,i1);
(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))();
*/
}

boost::bindBoost库中的一个函数对象绑定工具,它可以将函数或成员函数与参数进行绑定,生成一个新的可调用对象。通过boost::bind,我们可以将一个函数或成员函数的参数部分绑定为特定的值,从而创建一个具有较少参数的新函数对象。 使用boost::bind,我们可以方便地实现函数的柯里化(currying)或参数绑定,以及将成员函数绑定到特定对象上。它在编写回调函数、多线程编程和泛型编程等场景下非常有用。 下面是一个简单的示例,展示了如何使用boost::bind: ```cpp #include <iostream> #include <boost/bind.hpp> void printSum(int a, int b) { std::cout << "Sum: " << a + b << std::endl; } class Foo { public: void printProduct(int a, int b) { std::cout << "Product: " << a * b << std::endl; } }; int main() { // 绑定全局函数 auto sumFunc = boost::bind(printSum, 2, 3); sumFunc(); // 输出:Sum: 5 // 绑定成员函数 Foo foo; auto productFunc = boost::bind(&Foo::printProduct, &foo, 4, 5); productFunc(); // 输出:Product: 20 return 0; } ``` 在上述示例中,我们使用boost::bind分别将全局函数printSum和成员函数printProduct与参数进行绑定,生成了新的函数对象sumFunc和productFunc。通过调用这些函数对象,我们可以执行原始函数,并传入绑定的参数。 值得注意的是,boost::bind可以将参数按位置绑定,也可以通过占位符(_1, _2, ...)指定参数的位置。这使得我们可以灵活地控制绑定的参数位置和传入的参数个数。 希望这个简单的解释能够帮助到你!如果你有任何进一步的问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值