可调用对象与function类模板(定义同一调用形式的可调用对象)

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

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

和其他对象一样,可调用的对象也有类型,每个lambda有它自己唯一的(未命名)类类型,函数及函数指针的类型则由其返回值类型和实参类型决定,然而俩个不同的类型的可调用对象却可能共享同一种调用形式,调用形式指明了返回的类型以及传递给调用的实参类型。不同类型可能具有相同的调用形式,对于几个可调用对象共享同一个调用形式的情况,有时我们会希望把它们看成具有相同的类型。

上面这些可调用对象分别对其参数执行了不同的算术运算,尽管它们的类型各不相同,但是共享同一种调用形式: int ( int , int )
我们可能希望使用这些可调用对象构建一个简单的桌面计算器,为了实现这一目的,需要定义一个函数表,用来存储指向这些可调用对象的"指针",当程序需要执行某个特定的操作时,从表中查找该调用的函数,这个表可以通过map实现,关键字为string,值为对应函数,则可以这样定义 

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

 这样我们可以将add的指针添加到binops中,但是我们不能将mod或者divide存入binops,问题在于mod是个lambda表达式,每个lambda有它自己的类类型,该类型与存储在binops中的值的类型不匹配。(引用至C++primer,但个人实践时是可以进行insert的)

binops.insert({"+",add}); //{"+",add}是一个pair
binops.insert({"%",mod}); //错误mod不是一个函数指针

标准库function类型

可以用function来定义同一调用形式的可调用对象的类型,这样就可以解决上面的问题。

function是一个模板,和我们使用过的其他模板一样,当创建一个具体的function类型时我们必须提供额外的信息,这里的额外信息指该function类型能够表示的对象的调用形式,因此,我们可以用这个新声明的类型表示任意一种桌面计算器用到的类型。

我们能把所有可调用对象,包括函数指针、lambda或者函数对象在内,都添加到这个map中

重载的函数与function

我们不能(直接)将重载函数的名字存入function类型的对象中,这样会产生二义性

int add(int i, int j)
{
	return i + j;
}

double add(double i, double j)
{
	return i + j;
}

int main()
{
	map<string, function<int(int, int)>> binops;
	binops.insert({ "+",add });  //错误,无法确认添加哪个add
}

解决上述二义性问题的一条途径是存储函数指针,也可以使用lambda来消除二义性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值