C++:27---function模板(functional头文件)

引入

  • 在介绍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); } })

 

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值