C++仿函数 函数适配器 函数包装器

1 仿函数

仿函数:类模仿函数调用行为,实质是无名对象调用重载()的函数

一般仿函数用于排序准则或一些算法准则

标准库中的仿函数

算术类 关系类 逻辑类

        

#include<iostream>
#include<functional>
using namespace std;

//仿函数 类模仿函数的调用行为

class Sum
{
public:
	int operator()(int a, int b)
	{
		return a + b;;
	}
	int operator()(int a, int b, int c)
	{
		return a + b + c;
	}
protected:

};

int main()
{
	Sum s;
	cout << "显示调用重载函数" << s.operator()(1, 3) << endl;
	cout << "隐式调用" << s(1, 3) << endl;
	//用{} ()帮助编译器解析,不加()或 {}解析为构造函数
	//类模仿函数的调用行为--仿函数
	cout << "无名调用" << Sum()(1, 3) << endl;
	cout << "无名调用" << Sum{}(1, 3, 5) << endl;
	//标准库中算术 + - * 
	cout << plus<int>{}(1, 3) << endl;
	cout << minus<int>{}(1, 3) << endl;
	cout << multiplies<int>{}(1, 3) << endl;
	//==  <=
	cout << equal_to<int>{}(1, 3) << endl;
	cout << less_equal<int>{}(1, 3) << endl;
	//逻辑 与 非
	cout << endl << logical_and<int>()(1, 3) << endl;
	cout << logical_or<int>()(1, 3) << endl;
	cout << logical_not<int>()(1) << endl;

	return 0;
}

2  函数适配器

        用来绑定函数调用时的参数,让函数适应其他的调用的用法。

        利用bind函数

        bind()函数需要函数指针,占位符

        占位符 std::placeholders::_1 ;  标准库总共有20个这样的占位符,表示这个参数依照原样传参。未使用占位符的地方,如果绑定了固定值,则在函数调用时可以省略这个参数,如果依据传参则使用绑定的值。

        可以搭配greater  less lambad等使用

        利用占位符可以形成不同的调用形态

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

int Max(int a, int b)
{
	return a > b ? a : b;
}
void print(int(*pMax)(int, int), int a, int b)
{
	cout << pMax(a,b)<<endl;
}

void printData(int a, string b, double c)
{
	cout << "调用函数 "<< endl;
}

class Test
{
public:
	void print(int a, int b)
	{
		cout << a << " " << b << endl;
	}
	static void printSta(int a, int b)
	{
		cout << "static:"<<a <<" "<< b << endl;
	}
protected:
};
//绑定类中的函数
void testclassFunc()
{
	Test test;
	auto pfun = bind(&Test::print,&test,std::placeholders::_1,22);
	pfun(43);
	auto pfun2 = bind(Test::printSta,std::placeholders::_1,33);
	pfun2(35);
}


//  通过占位符调整参数位置,形成不同的调用形态
void test()
{
	auto testFunc = bind(printData, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
	printData(1,"hahada",9.99);
	//testFunc(1,"hahada",9.99);绑定之后 调用时错误的
	testFunc(9.99,1,"hahha");//对的  函数调用时的占位符表示原函数中参数要去的位置
								// 原函数参数  int string  double
								// 调用的占位符  2   3     1
								// 表示原来的int 去2号为,string去3号为,double去1号位

}

int main()
{
	cout << Max(1, 3) << endl;
	//基本用法
	//std::placeholders::_1   第一个参数占位符 ,使用时表示第一个参数按原样传参,标准库提供了20个占位符
	//bind()  绑定函数  
	auto pMax = bind(Max,std::placeholders::_1,100);	//第二个参数固定为100
	cout << pMax(12) << endl;//原本Max函数需要两个参数,现在绑定之后只需要传一个参数即可
	//只是增加调用行为 并没有改变函数指针类型
	cout << pMax(12, 34) << endl;	//绑定之后传第二个参数无效

	vector<int> data = {111,22,333,40,54,5,56};
	cout << count_if(data.begin(),data.end(),bind(greater<int>(),std::placeholders::_1,40))<<endl;
	// count_if 条件统计函数,在指定区间内满足条件的个数
	//bind()  这里绑定的是greater函数,筛选>40的个数
	cout << count_if(data.begin(), data.end(), [](int a) { return a > 60; }) << endl;

	test();

	testclassFunc();

	return 0;
}

3 函数包装器

        函数包装器:就是把函数指针包装成一个对象,利用对象调用函数。

        一旦函数指针被函数包装器包装了,那这个函数包装器的对象可以直接替换函数指针的用法去调用函数

        function<函数返回值类型(参数类型)>

#include<iostream>
#include<functional>
#include<string>

using namespace std;

int Max(int a, int b)
{
	cout << "包装普通函数" << endl;
	return a > b ? a : b;
}

class MM
{
public:
	void print(int a)
	{
		cout << "类中的成员函数" << a << endl;
	}
	static void printStatic(int b)
	{
		cout << "静态函数" << b << endl;
	}
	friend ostream& operator<<(ostream& out, MM object)
	{
		out << object << endl;
		return out;
	}
protected:
};

class Test
{
public:
	void operator()(string str)
	{
		cout << "包装仿函数:" << endl;
	}
protected:
};

void printData(int a, MM mm, string str)
{
	cout << "测试包装bind" << endl;
}
void testFunBind()
{
	function<void(MM, string, int)>  pB = bind(printData, std::placeholders::_3, std::placeholders::_1, std::placeholders::_2);
	pB(MM(),"lalla",22);
}



int main()
{
	//包装普通函数
	function<int(int, int)> funMax(Max);	// funMax 定义的对象,  Max是函数指针
	cout << funMax(1,22);
	//也可以用以下方式
	function<int(int, int)> funMax2 = Max;
	//包装类中的 函数
	cout << endl;

	MM mm;
	//包装静态函数
	function<void(int)> funS(MM::printStatic);
	funS(2);
	//包装成员函数  利用bind
	function<void(int)> funP(bind(&MM::print, &mm, std::placeholders::_1));
	funP(222);

	//包装仿函数
	Test test;
	function<void(string)> pT = test;
	pT("lalal");

	//包装bind
	testFunBind();
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值