算法的谓词(引入lambda)

谓词

含义

指可调用的表达式,作为算法的一个实参传进去。标准库算法用的谓词只有一元谓词(接受一个参数)和二元谓词

实例

通过定义一个可调用函数,作为参数传入sort函数。

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
#include <typeinfo>
using namespace std;

bool isShorter(const string &s1, const string &s2)  //二元谓词
{
    return s1.size()<s2.size();
}

int main() {
    vector<string> vec ={"01","0"};
    sort(vec.begin(), vec.end(), isShorter);
    for(auto &ele: vec)
        cout<<ele<<endl;

    return 0;
}

lambda

动机

算法函数支持谓词固定,比如find_if函数只接受一元谓词,但你写的谓词是接受好多参数,这样就用不了。

bool isShorter1(const string &s1, const int &sz)
{
    return s1.size()>= sz;
}

//找到长度大于sz的字符串
find_if(vec.begin(), vec.end(), isShorter1);  //xxx。不支持二元谓词

可调用对象

函数、函数指针、重载了调用运算符的类、lambda表达式。

定义形式

[capture list](param list)->return type { fuction body; }  // (param list)->return type可没有

返回类型可省略,这样人家就推断类型(不要相信,很可能错误类型)

捕获只用于局部非static变量

1、捕获列表是捕获lambda表达式所在函数内的局部非static变量,就是捕获普通局部变量,局部静态想用就用。

2、捕获列表为空可以使用当前函数之外的任何在当前函数作用域里的变量

用法

把多的参数设为捕获。

find_if(vec.begin(), vec.end(), [sz](const string &a){ return a.size()>=sz}); //形参只有一个a了

lambda的捕获和返回

lambda定义的本质

lambda可看作同时定义一个类类型和创建一个对象。对象是匿名的。

值捕获是创建lambda时拷贝

捕获列表的值捕获是创建时拷贝,参数列表是调用时拷贝。

void fcn()
{
       int j = 42;
       auto f = [j]{return j};
       j = 0;
       
       auto m = f();   //还是输出42
}

引用捕获不拷贝 ,是创建lambda时绑定

void fcn()
{
       int j = 42;
       auto f = [&j]{return j};
       j = 0;
       
       auto m = f();   //输出0
}

最后返回引用时要保证引用的对象存在

隐式捕获

可以使用[&]或[=],即直接隐式捕获,挺方便的。

find_if(vec.begin(), vec.end(), [=](const string &a){ return a.size()>=sz}); //sz不用显式捕获了了

 推断的类型不靠谱

transform(vi.begin(). vi.end(), vi.begin(), [](int i) {if(i<0) return -i; else return i;}); //xxx。很不幸推断成void了

//改成
transform(vi.begin(). vi.end(), vi.begin(), [](int i)->int {if(i<0) return -i; else return i;});


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值