引入

* 在介绍function之前,先介绍下面的知识:
* 有时,不同类型的对象可能共享同一种调用形式。例如下面的三种类型,都共享同一种调用形式:int(int,int); int add(int i, int
j) { return i + j; } auto mod = [](int i, int j) {return i * j; }; struct
divide { int operator()(int denominator,int divisor) { return denominator /
divisor; } };
* 为了使用这些可调用对象,我们可以定义一个函数表用于存储指向这些可调用对象的“指针”。我们可以通过map来实现:
* 参数1用一个string来表示这个对象可以用来干嘛
* 参数2为函数指针 map<string, int(*)(int,int)> binops; binops.insert({ "+",add
});//正确 binops.insert({ "%",mod });//错误
* 然后第二个是错误,因为lambda是个表达式,每个lambda都有自己的类类型,该类型与存储在binops中的值的类型不匹配
一、function模板简介

* 我们可以用function的标准库类型解决上述问题
*
新版本标准库中的function类与旧版本中的unary_function和binary_function没有关联,后两个类已经被更通用的bind函数替代了

二、使用

* 当使用该模板时,必须提供额外的信息来表示能够表示的对象的调用形式
演示案例

* function模板接受两个int、返回一个int的可调用对象 function<int(int, int)> f1 = add;
function<int(int, int)> f2 = divide(); function<int(int, int)> f3 = [](int i,
int j) {return i*j; }; cout << f1(4,2)<< endl; //6 cout << f2(4, 2) << endl;//2
cout << f3(4, 2) << endl;//8
重新定义map

* 我们通过使用function模板重新定义上面的map map<string, function<int(int, int)>> binops;
binops = { {"+",add}, {"-",std::minus<int>()}, {"/",divide()}, {"*",[](int
i,int j) {return i*j; }}, {"%",mod} }; binops["+"](10, 5); //调用add(10,5);
binops["-"](10, 5); //使用minus<int>对象的调用运算符 binops["/"](10, 5);
//使用divide对象的调用运算符 binops["*"](10, 5); //调用lambda函数对象 binops["%"](10, 5);
//调用lambda函数对象
三、重载的函数与function模板的关系

* 规则:不能直接将重载函数的名字存入到function类型的对象中,会产生二义性
* 解决方法:在模板中存储函数指针而非函数的名字
错误演示以及正确案例

* 错误案例 int add(int i, int j); long add(long i, long j); map<string,
function<int(int, int)>> binops; binops.insert({ "+",add });//错误,产生二义性
* 正确方法  int add(int i, int j); long add(long i, long j); int(*fp)(int, int) =
add; //函数指针 map<string, function<int(int, int)>> binops; binops.insert({ "+",fp
});//正确
*
同样,我们也能使用lambda来消除二义性。lambda内部的函数传入了两个int,因此该调用只能匹配接受两个int的add函数版本,而这也正是执行lambda时真正调用的函数
int add(int i, int j); long add(long i, long j); map<string, function<int(int,
int)>> binops; binops.insert({ "+",[](int a,int b) {return add(a,b); } })
 

技术
©2019-2020 Toolsou All rights reserved,
JAVA 把字符串转换成数字类型函数基本定义和使用‘未完待续hive压缩&&hdfs合并小文件数字滚动抽奖小程序什么是内存泄漏,常见引起引起内存泄漏的原因,及解决办法华为Mate 40 Pro+ 5G曝光:徕卡电影镜头、陶瓷机身判断当前对象是不是数组的4种方式Vue页面跳转传递参数及接收Dialog 中 使用 EventBus 问题Spring Boot教程十六:SpringBoot注入类实现多线程