C++ | function和bind

可调用对象

可调用对象的定义:(满足一个即可)

  1. 是一个函数指针
  2. 是一个具有operator()成员函数的类对象(就是仿函数)
  3. 是一个可被转换为函数指针的类对象
  4. 是一个类成员(函数)指针

关于一个可被转换为函数指针的类对象的举例:

struct Bar
{
	using fr_t = void(*) (void);//返回值为空参数为空的函数指针类型定义为fr_t
	static void func(void)
	{
	//...
	}
	operator fr_t(void)
	{
		return func;
	}
};

int main()
{
	Bar bar;
	bar();//调用func
	//等价于
	bar.operator Bar::fr_t()();
	
}

bar()调用过程,调用operator fr_t(void),随后返回一个目标函数指针,然后变为func()

是一个类成员(函数)指针举例

struct A
{
	int a;
	int b;
	void mem_func(void)
	{
		//...
	}
};

void fun()
{

}
int main()
{
	void (A:: * fun_ptr)(void) = &A::mem_func;
	int A::* b_ptr = &A::b;//b_ptr的值为0x00000004
	A aa;
	(aa.*fun_ptr)();
	//fun_ptr(&aa);err
	void (*p)(void) = &fun;
	p();
	
}

C+11通过提供function和bind统一了可调用对象的各种操作

function

是一个可调用对象的包装器.他是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象

实现原理:

template<typename R, typename... A>
class myfunction<R(A...)>
{
public:
	using PFUNC = R(*)(A...);
	myfunction(PFUNC pfunc) :_pfunc(pfunc) {}
	R operator()(A... arg)
	{
		return _pfunc(arg...); // hello(arg)
	}
private:
	PFUNC _pfunc;
};

使用举例:

void call_when_even(int x,const std::function<void(int>& f)
{
	if(!(x&1))
	{
		f(x);
	}
}

void output(int x)
{
	std::cout<<x<<" ";
}

int main()
{
	for(int i=0;i<10;++i)
	{
		call_when_even(i,output);//将偶数打印
	}
}

bind

bind用来将可调用对象与其参数一起进行绑定,绑定后可使用function进行保存
两大作用:
1.将可调用对象与其参数一起绑定成一个仿函数
2.将多元可调用对象转成一元或者(n-1)元可调用对象,就是先绑定部分参数.

bind1st

可以绑定第一个值,可以将一个二元操作转换为一元操作。

template<class _Fn2>
	class binder1st
		: public unary_function<typename _Fn2::second_argument_type,
			typename _Fn2::result_type>
	{	// functor adapter _Func(stored, right)
public:
	typedef unary_function<typename _Fn2::second_argument_type,
		typename _Fn2::result_type> _Base;
	typedef typename _Base::argument_type argument_type;
	typedef typename _Base::result_type result_type;

	binder1st(const _Fn2& _Func,
		const typename _Fn2::first_argument_type& _Left)
		: op(_Func), value(_Left)
		{	// construct from functor and left operand
		}

	result_type operator()(const argument_type& _Right) const
		{	// apply functor to operands
		return (op(value, _Right));
		}

	result_type operator()(argument_type& _Right) const
		{	// apply functor to operands
		return (op(value, _Right));
		}

protected:
	_Fn2 op;	// the functor to apply
	typename _Fn2::first_argument_type value;	// the left operand
	};

		// TEMPLATE FUNCTION bind1st
template<class _Fn2,
	class _Ty> inline
	binder1st<_Fn2> bind1st(const _Fn2& _Func, const _Ty& _Left)
	{	// return a binder1st functor adapter
	typename _Fn2::first_argument_type _Val(_Left);
	return (binder1st<_Fn2>(_Func, _Val));
	}

从上面代码我们可以很简单的发现:

1.返回对象的类型为binder1st.
2.使用typename _Fn2::first_argument_type value;保存了绑定的值。
3._Fn2 op; 定义了被适配的函数。
4.提供调用操作符result_type operator()(argument_type& _Right).
5.调用操作中,使用被适配的函数,第一个值为绑定的值return (op(value, _Right));.

bind

bind返回一个stl内部定义的仿函数类型,可以直接赋给function,一般和占位符搭配使用,

struct A
{
	int a;
	int b;
	void output(int x,int y)
	{
		cout << x << y << endl;
	}
	
};


int main()
{
	A a;
	function<void(int, int)> fr = bind(&A::output, &a, placeholders::_1, placeholders::_2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值