c++ lambda函数_c++ functors 和 自定义比较函数

61af6e5d900005bf06744aa0c2efdbd4.png
刷题的时候经常用到堆,即stl里的priority_queue。自定义比较函数有几种方法,各种文章都在互相复读,我就记了lambda表达式那种,也没管实现原理,结果今天做题想在类里定义优先队列和比较函数就遭重了。题外话,某傻篮子复读机网站最近开始弹登陆框,赶紧死了得了☺️。

functor

在c++中functor就是一个定义了operator()运算符的class/struct。然后你就可以创建一个能和普通函数一样用的实例,而且还它可以有成员变量保存状态。

class 

lambda作为一个语法糖,会创建一个nameless functor。原理类似上面,但是还是有区别。lambda只能用auto推导他的类型,因为每一个lambda都是独一无二的,即使参数是相同的类型。或者你可以用std::function将他wrap。还有就是lambda是没有默认构造函数的。

comparator

priority_queue是一个模板类,和sort这种模板函数不同需要指定类型。要自定义compare,根据c++默认参数的规则需要把container的参数也给上。

template 

compare默认参数是less<>这个functor模板类。下面是greater的声明:

template 

在priority_queue中有一个成员变量comp存储Compare的实例,comp默认的值compare(),然而之前已经说过lambda表达式是没有默认构造函数的,所以只能传参给priority_queue的构造函数,同时因为只有编译器才知道lambda的类型,所以得用decltype(cmp)获取类型。

priority_queue

comparator调用的时候comp(a, b)即可,comp是compare的实例。

为什么可以用多种方式自定义函数?

  1. struct 重载operater<

默认的compare是less,less重载的operator()也要用到struct的operator<,相当于做了一个传递。

2. struct cmp { operator(){}}

这就是定义了一个functor,正是compare需要的。

3. lambda表达式

也是一个functor。

自定义比较函数的priority_queue作为class成员

问题就来了,如果用lambda的方法,需要auto,而auto的成员变量需要static,导致capture的其他类成员变量也要static,这显然是不可接受的。

那换struct cmp的方法,nested class/struct在c++11以前无法访问外面的类的成员,你需要保存一个outer类的引用

struct 

那用lambda方式怎么写,你需要std::function

function

可能新手(指我自己)会按照惯性这样写,然后看到一个error: unknown type name 'cmp'的错误,错误的原因是试图在声明成员变量的时候调用它的构造函数。

正确的做法是用delegating constructor,人话就是把他写在类的初始化列表里。同时注意,cmp和priority_queue的顺序。因为类的初始化顺序和定义顺序相同,和初始化列表顺序无关,需要保证顺序来保证cmp已经被创建了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值