weak bindのstd実現

4801 ワード

転載は出典を明記してください。http://blog.csdn.net/wangji163163/article/details/73698662
弱いbindが実現して、ファンクラブがメンバーであることを防止する時、bind shared_fromthisは自己参照を形成し、メモリのリークをもたらします。
#include 
#include 
#include 
namespace stdx = std;
template
class Weak_Binder0
{
	typedef stdx::weak_ptr<_class>				WP;
	typedef stdx::shared_ptr<_class>			SP;
	typedef stdx::functionFN;
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
class Weak_Binder
{
	typedef _Ret								RT;
	typedef stdx::weak_ptr<_class>				WP;
	typedef stdx::shared_ptr<_class>			SP;
	typedef stdx::functionFN;
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
Weak_Binder0<_class _args...=""> wbind(const stdx::shared_ptr<_class>& sp, void (_Class::*f)(_Args...))
{
	return Weak_Binder0<_class _args...="">(sp, f);
}
template
Weak_Binder0<_class _args...=""> wbind(const stdx::shared_ptr<_class>& sp, void (_Class::*f)(_Args...) const)
{
	return Weak_Binder0<_class _args...="">(sp, f);
}
template
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
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
Weak_Binder0<_class _args...=""> wbind(const stdx::weak_ptr<_class>& sp, void (_Class::*f)(_Args...))
{
	return Weak_Binder0<_class _args...="">(sp, f);
}
template
Weak_Binder0<_class _args...=""> wbind(const stdx::weak_ptr<_class>& sp, void (_Class::*f)(_Args...) const)
{
	return Weak_Binder0<_class _args...="">(sp, f);
}
template
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
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
",m,i); return i; } void print0() { printf("[%d]print0
",m); } }; int main(int argc, char** argv) { stdx::shared_ptr sp(new Test(1000)); int r(0); stdx::function f0 = ::wbind(sp, &Test::print0); stdx::function f1 = ::wbind(-1,sp, &Test::print1); f0(); r = f1(100);printf("r=%d
", r); sp.reset(); f0(); r = f1(100);printf("r=%d
", r); return 0; }
出力
$./test_sig 
[1000]print0
[1000]print1:100
r=100
r=-1
stdバージョンを実現しましたが、bookバージョンはまだ実現されていません。原因はbookのforwardとC+11の意味が違っています。