转载请注明出处:http://blog.csdn.net/wangji163163/article/details/73698662
弱bind实现,防止function是成员的时候,bind shared_from_this 形成自引用,导致内存泄露。
#include <stdio.h>
#include <memory>
#include <functional>
namespace stdx = std;
template<typename _Class, typename... _Args>
class Weak_Binder0
{
typedef stdx::weak_ptr<_Class> WP;
typedef stdx::shared_ptr<_Class> SP;
typedef stdx::function<void(_Class*,_Args...)>FN;
public:
Weak_Binder0(const WP& wp, const FN& f) :wp_(wp), f_(f) {}
void operator()(_Args&&... args) const { if (SP sp = wp_.lock())f_(sp.get(), stdx::forward<_Args>(args)...); }
private:
WP wp_;
FN f_;
};
template<typename _Ret, typename _Class, typename... _Args>
class Weak_Binder
{
typedef _Ret RT;
typedef stdx::weak_ptr<_Class> WP;
typedef stdx::shared_ptr<_Class> SP;
typedef stdx::function<RT(_Class*, _Args...)>FN;
public:
Weak_Binder(const RT& fail, const WP& wp, const FN& f) :fail_(fail), wp_(wp), f_(f) {}
_Ret operator()(_Args&&... args) const
{
if (SP sp = wp_.lock())return f_(sp.get(), stdx::forward<_Args>(args)...);
return fail_;
}
private:
RT fail_;
WP wp_;
FN f_;
};
template<typename _Class, typename... _Args>
Weak_Binder0<_Class, _Args...> wbind(const stdx::shared_ptr<_Class>& sp, void (_Class::*f)(_Args...))
{
return Weak_Binder0<_Class, _Args...>(sp, f);
}
template<typename _Class, typename... _Args>
Weak_Binder0<_Class, _Args...> wbind(const stdx::shared_ptr<_Class>& sp, void (_Class::*f)(_Args...) const)
{
return Weak_Binder0<_Class, _Args...>(sp, f);
}
template<typename _Ret, typename _Class, typename... _Args>
Weak_Binder<_Ret, _Class, _Args...> wbind(const _Ret&& fail, const stdx::shared_ptr<_Class>& sp, _Ret(_Class::*f)(_Args...))
{
return Weak_Binder<_Ret, _Class, _Args...>(fail, sp, f);
}
template<typename _Ret, typename _Class, typename... _Args>
Weak_Binder<_Ret, _Class, _Args...> wbind(const _Ret&& fail, const stdx::shared_ptr<_Class>& sp, _Ret(_Class::*f)(_Args...) const)
{
return Weak_Binder<_Ret, _Class, _Args...>(fail, sp, f);
}
//
template<typename _Class, typename... _Args>
Weak_Binder0<_Class, _Args...> wbind(const stdx::weak_ptr<_Class>& sp, void (_Class::*f)(_Args...))
{
return Weak_Binder0<_Class, _Args...>(sp, f);
}
template<typename _Class, typename... _Args>
Weak_Binder0<_Class, _Args...> wbind(const stdx::weak_ptr<_Class>& sp, void (_Class::*f)(_Args...) const)
{
return Weak_Binder0<_Class, _Args...>(sp, f);
}
template<typename _Ret, typename _Class, typename... _Args>
Weak_Binder<_Ret, _Class, _Args...> wbind(const _Ret& fail, const stdx::weak_ptr<_Class>& sp, _Ret(_Class::*f)(_Args...))
{
return Weak_Binder<_Ret, _Class, _Args...>(fail, sp, f);
}
template<typename _Ret, typename _Class, typename... _Args>
Weak_Binder<_Ret, _Class, _Args...> wbind(const _Ret& fail, const stdx::weak_ptr<_Class>& sp, _Ret(_Class::*f)(_Args...) const)
{
return Weak_Binder<_Ret, _Class, _Args...>(fail, sp, f);
}
class Test
{
int m;
public:
Test(int k):m(k)
{
}
int print1(int i)
{
printf("[%d]print1:%d\n",m,i);
return i;
}
void print0()
{
printf("[%d]print0\n",m);
}
};
int main(int argc, char** argv)
{
stdx::shared_ptr<Test> sp(new Test(1000));
int r(0);
stdx::function<void(void)> f0 = ::wbind(sp, &Test::print0);
stdx::function<int(int)> f1 = ::wbind(-1,sp, &Test::print1);
f0();
r = f1(100);printf("r=%d\n", r);
sp.reset();
f0();
r = f1(100);printf("r=%d\n", r);
return 0;
}
$./test_sig
[1000]print0
[1000]print1:100
r=100
r=-1
实现了std版本,boost版本还未实现,原因是boost的forward与C++11的寓意不一样。