weak bind的std实现

转载请注明出处: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的寓意不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值