可调用对象与function

C++语言中有几种可调用的对象:函数、函数指针、lambda表达式、bind创建的对象、以及重载了函数调用运算符的类。
可调用的对象也有类型,例如,每个lambda有它自己唯一的(未命名)类类型,函数及函数指针的类型由其返回值类型和实参类型决定。

不同类型可能具有相同的调用形式

//普通函数
int add(int i, int j) { return i + j; }

//lambda,其产生一个未命名的函数对象类
auto mod = [](int i, int j) { return i % j; };

//函数对象类
class divide {
    int operator() (int denominator, int divisor)
    {
        return denominator / divisor;
    }
}

上面这些可调用对象分别对其参数执行了不同的算术运算,尽管它们的类型各不相同,但是共享同一种调用形式:int (int , int)

可以通过定义一个函数表来存储指向这些可调用对象的”指针“。当程序需要某执行某个特定的操作时,从表中查找该调用的函数。在C++中,函数表可以通过map来实现

标准库function类型
function定义在functional头文件中,下表列出了function定义的操作:

function是一个模板,当创建一个具体的function类型时,必须提供额外的信息,例如function

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;
cout<<f2(4, 2)<<endl;
cout<<f3(4,2)<<endl;

使用function类型重新定义map:

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

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

map<string, function<int(int, int)>> binops = {
{"+", add}, 
{"-", std::minus<int>()},                                   {"/",divide()}, 
{"*", [](int i, int j) { return i*j; }},
 {"%", mod}
};

则调用形式为:

binops["+"](10,5);
binops["-"](10,5);
binops["/"](10,5);
binops["*"](10,5);

重载的函数与function:
不能直接将重载函数的名字存入function类型的对象中

int add(int i, int j) { return i+j; }
Sales_data add(const Sales_data&, const Sales_data&);
map<string, fucntion<int(int, int)>> binops;
binops.insert({"+", add});  //错误,哪个?

解决上述二义性问题的一条途径是存储函数指针而非函数的名字:

int (*fp)(int, int) = add;  //指针所指的add是接受两个int的版本
binops.insert({"+", fp});   //正确:fp指向一个正确的add版本

同样可以使用lambda来消除二义性:

//正确:使用lambda来指定我们希望使用的add版本
binops.insert({"+", [](int a, int b){ return add(a,b)}});

lambda内部使用的函数调用传入了两个int,因此该调用只能匹配接受两个int的add版本。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值