c++笔记记录3

bind绑定器和function函数对象

1.函数对象operator();

​ 一元函数对象,operator()(const T&val ),括号里面只有一个

​ 二元函数对象,operator()(const T&val,const T&val2 ),括号里面有2个

2.绑定器

​ bind1st :operator()是一个函数适配器,它的作用是将一个值绑定到二元函数对象的第一个参数,从而创建一个新的一元函数对象。

​ bind2nd :operator()是一个函数适配器,它的作用是将一个值绑定到二元函数对象的第二个参数上,从而创建一个新的一元函数对象。

find_if(vec.begin(),vec.end(),一元函数对象);
但是great less 是二元, 所以要用到绑定器
绑定器+二元函数对象=》一元函数对象

bind1st + greater bool operator() (70, const _Ty& _Right)

bind2nd: + less bool operator()(const _Ty&Left,70)

​		greater  	a>b
​		less 		a<b

下面都是返回一个第一个大于70的元素,如果没有这样的元素,则迭代器it1/2将等于vec.end()。

auto it1=find_if(vec.begin(),vec.end(),bind1st(greater<int>(),70))//70>value
auto it2=find_if(vec.begin(),vec.end(),bind2nd(less<int>(),70))//value<70

3.c++11从boost库引入bind绑定器和function函数对象机制

4.lambda表达式 底层依赖函数对象机制的实现

sort(vec.begin(),vec.end())//小到大
sort(vec.begin(),vec.end(),greater<int>());//从大到小排序,默认小到大
sort(vec.begin(),vec.end(),[](int a, int b) { return a > b; });//从大到小排序,默认小到大

[]不捕获外部变量

[=] 以传值方式捕获

[&]以传引用的方式捕获

[this]捕获外部的this

[=,&a]以传值捕获,但是a传引用捕获

[this]捕获外部this

[a,b]以值传递的方式捕获外部变量a和b

语法:

 [捕获外部变量](形参)->返回值{操作代码}

在这里插入图片描述

auto fun3=[&](){
	int tmp=a;
	a=b;
	b=tmp;
}
或者
auto fun3=[&a,&b](){
	int tmp=a;
	a=b;
	b=tmp;
}
fun3();

5.function函数对象
lambda表达式,它们只能使用在一个语句中,但是function让其可以多条使用

从function的类模板定义出看到希望用一个函数类型实例化function

function<void()>func1=hello1;
func1(); //func1.operator()=>hello1()

function<void(string)>func2=hello2;
func2("hello hello ");//func2.operator()(string str)=>hello2(str);

function<int(int,int)>func4=[](int a,int b)->int{return a+b;}
func3(100,200);//300

其实就是用func2替代了那个函数对象,进行包装调用的时候传入参数

​ 1.用函数类型实例化function

​ 2.通过function调用operator()函数的时候,需要根据函数类型传入参数

类的成员调用必须要成员对象

void (Test::*pfunc)(string)//调用
function<void(Test*,string)>func4=&Test::hello;
func4(&Test(),"call test::hello");

普通函数不用

void(*pfunc)(string);

function 可以用map将数字和函数结合起来

然后调用的数字就执行相应的函数,比较好的功能

	map<int, function<int(int, int)>> calc_map;
	calc_map[1] = [](int a, int b)->int {return a + b; };
	calc_map[2] = [](int a, int b)->int {return a - b; };
	calc_map[3] = [](int a, int b)->int {return a * b; };
	calc_map[4] = [](int a, int b)->int {return a / b; };

又比如选择不同数字对应不同的书籍 key:数字 value:书籍

6.模板的完全特例化和非完全(部分)特例化

有原模板才能提供完全特例化
template<typename T>
bool compare(T a,T b){
return a>b;
}
template<>//完全特例化
bool compare<const char*>(const char* a,const char* b)
{
	return strcmp(a,b)>0;
}
int main(){
compare(10,20)//int 
compare("aa","bb");//T const char*
}

7.function的实现原理

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

using namespace std;

// 先提供统一的模板
template<typename T>
class MyFunction {

};

// 根据具体情况细分(返回值和单个形参)
template<typename R, typename A1>
class MyFunction<R(A1)> {
public:
	using PFUNC = R(*)(A1);
	MyFunction(PFUNC pfunc) :_pfunc(pfunc) {

	}
	R operator()(A1 arg) {
		return _pfunc(arg);
	}

private:
	PFUNC _pfunc;
};

int print(string str) {
	cout << str << endl;
	return str.size();
}

int main() {
	MyFunction<int(string)> func(print);
	int len = func("hello world"); //func.operator()("hello world")
	cout << len << endl;
	return 0;
}

using 可以重新定义函数名
using PFUNC = R(*)(A1);:这里使用 using 关键字定义了一个类型别名 PFUNC。PFUNC 是一个指向函数的指针,该函数接受一个类型为 A1 的参数并返回类型为 R 的值。换句话说,PFUNC 是一个函数指针类型,它可以指向任何符合这个签名的函数。
在这里插入图片描述

可变参数… 可以接受一组形参变量
在这里插入图片描述

在这里插入图片描述

7.bind绑定器=》返回结果还是一个函数对象,功能比bind1st和bind2nd强大

需要operator()重载函数

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

using namespace std;

void show(string str) {
	cout << str << endl;
}

void add1(int a, int b) {
	cout << a + b << endl;
}

class Test {
public:
	void add2(int a, int b) {
		cout << a + b << endl;
	}
};

int main() {
	bind(show, "hello")();  // bind(show, "hello")返回的是function<void()>函数对象
	bind(add1, 1, 2)();     // bind(add1, 1, 2)返回的是function<void()>函数对象
	bind(&Test::add2, Test(), 1, 2)();

	// 使用类型占位符,后续调用时再传
	// bind(show, placeholders::_1)返回的是function<void(string)>函数对象
	bind(show, placeholders::_1)("hello"); 
	// 最多绑定_20参数
	// bind(add1, placeholders::_1, placeholders::_2)返回的是function<void(int, int)>函数对象
	function<void(int, int)> func = bind(add1, placeholders::_1, placeholders::_2);
	func(1, 2);
	return 0;
}

//参数占位符

bind(hello,placeholders::_1)("hello bind 2");
bind(sum,placeholders::_1,placeholders::_2)(200,300);

//绑定器出了语句无法继续使用=》function

function<void(string )>func1=bind(hello,placeholders::_1);
func1("hello ");//此处可以将bind返回的绑定器binder复用起来
  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值