STL学习笔记(5)- STL的函数适配器bind1st和bind2nd

文章目录


  • bind1st 是将一个二元函数的第一个参数绑定为固定值的函数(实质上是仿函数类)
  • bind2nd 是将一个二元函数的第二个参数绑定为固定值的函数(实质上是仿函数类)

他们再使用的时候都需要加上头文件<functional>

1. bind1st

下面是一个关于 bind1st 的简单示例:

#include <iostream>
#include <functional>

template<typename T>
class MLess : public std::binary_function<T, T, bool>
{
public:
	bool operator() (const T& a, const T& b) const{
		return a < b;
	}
};

int main(int argc, char** argv)
{
	auto lessObj = std::bind1st(MLess<int>(), 5);
	std::cout << lessObj(6) << std::endl;
	system("pause");
	return 0;
}

这里我们先定义了一个仿函数 MLess 用来进行两个数的比较,使用函数 bind1stMLess<int>()(const T& a, const T& b) 的第一个参数绑定为5,然后传入后续的参数与5进行比较,很显然 5 < 6 的结果为 true
程序的运行结果为:
1

首先我们的自定义函数继承自类 binary_function , 关于类 binary_function 的定义很简单,源码如下:

template<class _Arg1,
	class _Arg2,
	class _Result>
	struct binary_function
	{	// base class for binary functions
	typedef _Arg1 first_argument_type;
	typedef _Arg2 second_argument_type;
	typedef _Result result_type;
	};

这是一个二元函数的模板类,定义两个输入参数,一个返回值。

关于 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));
	}

从代码中,可以轻松看出, bind1st 是一个函数模板,需要传入两个参数,_Func_Leftbinder1st 是一个仿函数类,构造函数中将 _Func 赋值给了成员 op_Left 赋值给我成员 value,重载的 () 正好调用的函数 op(value, _Right)

我们上面的例子中,

auto lessObj = std::bind1st(MLess<int>(), 5);

实际上是返回一个仿函数类 binder1st ,成员 opMLess<int>() 对象, value5

而调用

lessObj(6)

时,实际上是在调用函数

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

也就是这么调用

binder1st<MLess<int>()>(6) 
// 也就相当于执行下面这句
MLess<int>()(5, 6)

2. bind2nd

bind2nd 的内部实现跟 bind1st 类似,这里就不缀余了。下面是一个 bind2nd 的简单实用示例,将列表 nList 中的 >30 的数打印出来:

#include <iostream>
#include <functional>
#include <algorithm>
#include <list>

template<typename T>
class MTestClass : public std::binary_function<T, T, void>
{
public:
	void operator() (const T& a, const T& b) const{
		if (a > b)
			std::cout << a << std::endl;
	}
};

int main(int argc, char** argv)
{
	std::list<int> nList;
	nList.push_back(10);
	nList.push_back(20);
	nList.push_back(30);
	nList.push_back(40);
	nList.push_back(50);
	nList.push_back(60);

	std::for_each(nList.begin(), nList.end(), std::bind2nd(MTestClass<int>(), 30));
	
	system("pause");
	return 0;
}

程序的运行结果为:
40
50
60


作者:douzhq
个人主页:https://www.douzhq.cn
文章同步页:https://douzhq.cn/stl_bind1standbind2nd/

发布了88 篇原创文章 · 获赞 79 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/douzhq/article/details/90385580