《c++primer》第五版学习笔记:lambda表达式

原书P345

目录

介绍lambda

lambda表达式格式

​lambda捕获和返回

值捕获

引用捕获 

隐式捕获

可变lambda

参数绑定

标准库bind函数


介绍lambda

我们可以向算法(这里的算法指标准库中实现的可调用的一些接口)传递任何类别的调用对象。

对于一个对象或一个表达式,如果可以对其使用调用运算符,则称它为可调用的。即,如果e是一个可调用的表达式,则我们可以编写代码e(args),其中args是一个逗号分隔的一个或多个参数的列表。

lambda表达式格式

一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。与任何函数类似,一个lambda具有一个返回类型,一个参数列表和一个函数题。但与函数不同,lambda可能定义在函数内部,一个lambda表达式具有如下形式:

[capture list](parameter list)->return type{function body}

其中,capture list是一个lambda所在函数中定义的局部变量的列表,其余的和普通函数一样。

lambda中忽略括号和参数列表等价于指定一个空参数列表。

如果忽略返回类型,lambda根据函数体中的代码推断出返回类型。

举个栗子:


lambda捕获和返回

当定义一个lambda时,编译器生成一个与lambda对应的新的类类型。可以这样理解,当向一个函数传递lambda时,同时定义了一个新类型和该类型的一个对象:传递的参数就是此编译器生成的类类型的未命名对象。类似的,当使用auto定义一个lambda初始化的变量时,定义了一个从lambda生成的类型的对象。

值捕获

类似参数传递,变量的捕获方式可以是值或引用:

引用捕获 

隐式捕获

 除了显式列出我们希望使用的来自所在函数的变量之外,还可以让编译器根据lambda中的代码来推断我们要使用哪些变量。=表示值捕获,&表示引用捕获:

wc=find_if(words.begin(),words.end(),
                [=](const string &s)
                    {return s.size()>=sz;});

混用显式和隐式捕获:

void biggies(vector<string> words,vector<string>::size_type sz,
                ostream &os=cout,char c=' ')
{
    for_each(words.begin(),word.end()
            [&,c](const string &s){os<<s<<c;});

    for_each(words.begin(),word.end()
            [=,&os](const string &s){os<<s<<c;});
}

捕获列表的一些规则如下表所示:

可变lambda

 

参数绑定

对于那种只在一两个地方使用的简单操作,lambda表达式是最有用的。如果我们需要在很多地方使用相同的操作,通常应该定义一个函数,而不是多次编写相同的lambda表达式。类似的,如果一个操作需要很多语句才能完成,通常使用函数更好。

如果lambda的捕获列表为空,通常可以用函数来代替它。

但是,对于捕获局部变量的lambda,用函数来替换它就不是那么容易了。例如我们用在find_if调用中的lambda比较一个string和一个给定大小。我们可以很容易地编写一个完成同样工作的函数:

bool check_size(const string &s,string::size_type sz)
{
    return s.size()>=sz;
}

但是,我们不能用这个函数作为find_if的一个参数。如前文所示,find_if接受一个一元谓词,因此传递给find_if的可调用对象必须接受单一参数,biggies传递给find_if的lambda使用捕获列表来保存iz。为了用check_size来代替此lambda,必须解决如何向sz形参传递一个参数的问题。

标准库bind函数

bind函数的格式如下:

auto newCallable=bind(callable,arg_list)

可以将bind函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来适应原对象的参数列表。

arg_list中的参数可能包含形如_n的名字,其中n是一个整数。这些参数是“占位符”,表示newCallable的参数,它们占据了传递给newCallable的参数的位置。

关于这个参数列表在书中的例子:

 

 

 

 

不过注意_1,_2等占位符是放在std::placeholders里边的,为了方便可以用using

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值