C++-标准库类型function介绍

可调用对象和调用形式

C++中有几种可调用对象

1.函数
2.函数指针
3.重载了调用运算符的类
4.lambda表达式
5.bind创建的对象

可调用对象有不同的类型,每个lambda有唯一的类类型,函数和函数指针的类型由参数和返回值决定。
不同类型的可调用对象可能有相同的调用形式,调用形式表明了调用返回的类型和传递给调用的实参类型,一种调用形式对应一个函数类型。如:

int(int,int)

是一个函数类型,它接受两个int,返回一个int

函数表的例子

考虑不同类型的可调用对象:

int add(int i,int j){return i+j};//函数类型
auto mod=[](int i,int j){return i%j};//lambda对应一个未命名的函数对象类
struct divide{//函数对象类
    int operator()(int i,int j){
        return i/j;
    }
}

以上三个可调用对象具有不同的类型,但是有相同的调用形式。
假设我们希望将上述函数对象做成一个函数表来进行调用,声明map:

map<string,int(*)(int,int)> binops;

添加add到map中

binops.insert({"+".add});//正确

但是我们不能将mod和divide加入map中,原因是mod和divide是类类型,而不是一个函数指针,与binops中的值类型不匹配

function救场

使用function标准库类型可以解决以上问题。function是一个模板,创建一个具体的类类型时我们需要提供额外的信息:调用形式。如:

function<int(int,int)>

这里声明了一个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};

重新声明map,我们就能把所有具有该调用形式的可调用对象添加到map中

binops.insert({"%",f2});
binops.insert({"/",f3});
//调用
binops["/"](10,5)//使用对象的调用运算符 =2
binops["%"](10,5)//调用lambda函数对象 =0

重载函数二义性问题

重载函数由于函数名相同,插入map时,会产生二义性问题:

int add(int i,int j);
float add(float i,float j);
binops.insert({"+",add});//错误

两种解决方法:

  1. 使用函数指针,明确指向某一个函数
  2. 使用lamda,调用特定版本的函数
binops.insert({"+",[](int i,int j){return add(i,j);}});
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mrbone11

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

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

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

打赏作者

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

抵扣说明:

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

余额充值