跳至主要內容

bind1st和bind2d使用

张威大约 3 分钟c/c++bind绑定器

bind1st和bind2d使用

  • bind1st和bind2d是STL中的;
  • bind1st和bind2d作用: 将二元函数对象的一个参数绑定,使其变为一元函数对象;
  • 缺点: 只能用于二元函数对象。
  • 函数对象: 对象拥有小括号重载函数open in new window的对象。
#include <functional>		--包含c++库中的所有的函数对象 bind1st
#include <algorithm>		--包含了c++库中的所有的泛型算法

例1—改变排序顺序

#include <iostream>
#include <vector> 
#include <functional>
#include <algorithm>
#include <ctime>
using namespace std;

template<typename Container>
void showContainer(Container& con)
{
	typename Container::iterator it = con.begin();
	//编译器是从上到下编译的,这个还没有实例化,它不知道这个名字作用域后面的iterator是类型还是变量
	//typename告知编译器后面类型的作用域后面是类型
	for (; it != con.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}

int main()
{
	vector<int> vec;
	srand(time(nullptr));
	for (int i = 0; i < 20; ++i)
	{
		vec.push_back(rand() % 100 + 1);//随机出来的数字,并不是有序的 
	}

	showContainer(vec);
	sort(vec.begin(), vec.end());//默认小到大排序,传入的是起始和末尾的后继的迭代器
	showContainer(vec);
	//greater 二元函数对象
	sort(vec.begin(), vec.end(), greater<int>());//大到小排序
	showContainer(vec);
	return 0;
}

greater是一个二元函数对象:(因为一次需要从容器中拿2个函数对象出来)

例2—将70按顺序插入到vec容器中

问题:将70按顺序插入到vec容器中

使用find_if函数需要传入一个**一元函数对象(**一次从容器中拿出一个元素和70进行比较 )

注意:库里面提供的函数对象,没有办法直接使用;怎么办?

使用绑定器,将二元函数对象转换为一元函数对象;

#include <iostream>
#include <vector> 
#include <functional>
#include <algorithm>
#include <ctime>
using namespace std;

template<typename Container>
void showContainer(Container& con)
{
	typename Container::iterator it = con.begin();
	for (; it != con.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}

template<typename Iterator, typename Compare>
Iterator my_find_if(Iterator first, Iterator last, Compare comp)
//遍历这2个迭代器之间的元素,如果满足函数对象的运算,就返回当前迭代器,如果都不满足,返回end()
{
	for (; first != last; ++first)
	{
		if (comp(*first))//comp.operator()(*first)一元函数对象,因为要从容器拿1个元素和它指定的元素比较
		//my_find_if需要1元函数对象,而在库里面都是二元的
		{
			return first;
		}
	}
	return last;
}

template<typename Compare, typename T>
class _mybind1st//绑定器是函数对象的一个应用
{
public:
	_mybind1st(Compare comp, T val)
		:_comp(comp), _val(val)
	{}
	bool operator()(const T& second)
	{
		return _comp(_val, second);//greater
	}
private:
	Compare _comp;
	T _val;
};

//mybind1st(greater<int>(), 70)
//mybind1st就是将函数对象封装了一下。
template<typename Compare, typename T>
_mybind1st<Compare, T> mybind1st(Compare comp, const T& val)
{
	//直接使用函数模板,好处是,可以进行类型的推演
	return _mybind1st<Compare, T>(comp, val);
}

int main()
{
	vector<int> vec;
	srand(time(nullptr));
	for (int i = 0; i < 20; ++i)
	{
		vec.push_back(rand() % 100 + 1);
	}

	showContainer(vec);
	sort(vec.begin(), vec.end());//默认小到大排序
	showContainer(vec);

	//greater 二元函数对象
	sort(vec.begin(), vec.end(), greater<int>());//大到小排序
	showContainer(vec);

	/*
	把70按顺序插入到vec容器当中   找第一个小于70的数字
	operator()(const T &val)
	greater   a > b
	less      a < b
	绑定器 + 二元函数对象 =》 一元函数对象
	bind1st: + greater bool operator()(70, const _Ty& _Right)
	bind2nd: + less bool operator()(const _Ty& _Left, 70)
	*/
	
	auto it1 = my_find_if(vec.begin(), vec.end(),
		mybind1st(greater<int>(), 70));
	//auto it1 = my_find_if(vec.begin(), vec.end(),bind2nd(less<int>(), 70));
	if (it1 != vec.end())
	{
		vec.insert(it1, 70);
	}
	showContainer(vec);

	return 0;
}