C++ STL 预定义的function object和Binder

头文件<functional>

预定义的function object

在这里插入图片描述

对对象排序或比较时,默认以less<>为比较准则,因此默认的排序操作总是产生升序.


Function Adapter和Binder

所谓的Function adapter(函数适配器,函数改造器),指能够将不通的函数对象结合起来的东西,它自身也是一个函数对象.

C++11引入了更方便更弹性的adapter.下面是C++11开始,C++STL提供的函数适配器

在这里插入图片描述

其中最重要的adapter就是bind(),它允许:

1.让一个函数对象配接合成新的函数对象

2.调用全局函数

3.针对对象、对象指针、对象智能指针调用成员函数

下面是一个Binder的典型应用:

int main()
{
	auto plus10 = bind(plus<int>(), placeholders::_1, 10);
	cout << "+10:  " << plus10(7) << endl;
	auto plus10times2 = bind(multiplies<int>(), bind(plus<int>(), placeholders::_1, 10), 2);

	cout << "+10 * 2: " << plus10times2(7) << endl;
	auto pow3 = bind(multiplies<int>(), bind(multiplies<int>(), placeholders::_1, placeholders::_1), placeholders::_1);
	cout << "x*x*x  " << pow3(7) << endl;
	auto inversdivide = bind(divides<double>(), placeholders::_2, placeholders::_1);
	cout << "invdiv: " << inversdivide(49, 7) << endl;
}

在这里插入图片描述

其中placeholders_1、_2、…是预定义占位符,被定义于命名空间placeholders

使用using指示符,可以缩短整个语句:

using namespace std;
using namespace std::placeholders;
Bind(plus<int>(),_1,10)

也可以直接调用binder而不必先为它建立一个对应的函数对象,比如:

Cout << bind(plus<int>(),_1,10)(32) << endl;

调用全局函数:

using namespace std;
using namespace std::placeholders;
char myToupper(char c)
{
	locale loc;
	return use_facet<ctype<char>>(loc).toupper(c);
}
int main()
{
	string s("Internationalization");
	string sub("Nation");
	string::iterator pos;
	pos = search(s.begin(), s.end(), sub.begin(), sub.end(), bind(equal_to<char>(), bind(myToupper, _1), bind(myToupper, _2)));
	if (pos != s.end())
	{
		cout << "\"" << sub << "\" is part of \"" << s << "\"" << endl;
	}
}

在这里插入图片描述

调用成员函数:

class Person
{
private:
	string name;
public:
	Person(const string& n) :name(n) {}
	void print()const
	{
		cout << name << endl;
	}
	void print2(const string& prefix)const
	{
		cout << prefix << name << endl;
	}
};
int main()
{

	vector<Person>coll{ Person("Tick"), Person("Trick"),Person{"Track"} };
	for_each(coll.begin(), coll.end(), bind(&Person::print, _1));
	cout << endl;
	for_each(coll.begin(), coll.end(), bind(&Person::print2, _1, "Person: "));
	cout << endl;

	bind(&Person::print2, _1, "This is: ")(Person("nico"));

}

在这里插入图片描述

Mem_fn()adapter

若有额外实参被传给成员函数,mem_fn就拿其中第一实参作为调用者,其他实参当做成员函数的实参:

...
for_each(coll.begin(), coll.end(), mem_fn(&Person::print));
mem_fn(&Person::print)(n);//calls n.print()
mem_fn(&Person::print2)(n,"Person: ");//calls n.print()
...

绑定至数据成员

map<string, int>coll;
int sum = accumulate(coll.begin(), coll.end(), 0, bind(plus<int>(), _1, bind(&map<string, int>::value_type::second, _2)));



以Function Adapter搭配用户自定义的Function Object

你也可以把binder用在你自定义的函数对象身上,下面展示了一份函数对象的完整定义:
template<typename T1, typename T2>
struct fopow
{
	T1 operator()(T1 base, T2 exp)const
	{
		return std::pow(base, exp);
	}
};
int main()
{
	vector<int>coll{ 1,2,3,4,5,6,7,8,9 };

	transform(coll.begin(), coll.end(), ostream_iterator<float>(cout, " "), bind(fopow<float, int>(), 3, _1));
	cout << endl;
	transform(coll.begin(), coll.end(), ostream_iterator<float>(cout, " "), bind(fopow<float, int>(), _1, 3));
	cout << endl;

}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值