【C++11】让程序更简洁—lambda表达式

336次阅读  |  发布于2年以前

C++11中,Lambda表达式是最常用的特性之一,有过java、python以及C#开发经验的人对lambda功能都不会陌生。lambda表达式来源于函数式编程,具备以下优点:

lambda表达式概念和语法lambda实际上是一个匿名函数,运行时能够捕获到程序范围内的变量,其定义方式如下:

[capture] (params) opt -> ret {body;} ;

在上面的定义中,capture可以根据不同的取值,捕获不同范围内的变量,具体如下:

capture形式 说明
[] 不捕获变量
[&] 引用捕获,捕获所有变量
[=] 按值捕获,捕获所有变量
[=,&foo] 按值捕获所有变量,按引用捕获foo变量
[foo] 按值捕获foo,不捕获其他变量
[this] 捕获类中的this指针

params是参数列表;opt是函数选项;ret是返回值类型;body是函数体,当然在实际的使用中,lambda表达式也可以省略函数返回值的定义。省略函数返回值的lambda表达式定义可以参考下面的示例:

auto fr = [](int a) { return (a+1); };

上面的代码在编译时,编译器会根据return的语句进行自动推导。lambda表达式按值捕获参数时是不能够修改捕获的变量的,如果要进行修改,改如何做?

如何修改按值捕获的变量?在使用lambda表达式时,如果使用按址引用,可以修改捕获的变量,如果是按值捕获同时又要修改变量时需要在定义时使用mutable关键字,而且要进行显示说明,如:


int a = 0;
auto fr = [=]() mutable {return a++;};

在这里需要提醒大家,如果要在lambda表达式中使用mutable,不管表达式中有没有参数选项,都要把参数列表加上。

由此可见:mutable的作用就要要取消const的作用。

lambda表达式和std::function配合使用在C++11中,lambda表达式类型有叫做“闭包类型”。

可以认为是一个带有operator()的类,于是可以将其和function配合使用,使用方法如下:

std::function<int(int)> fr = [](int a) {return a; };

同理,也可以和std::bind配合使用,只要将上面的代码稍作修改即可完成,具体如下:


std::function<int(void)> fr = std::bind([](int a) {return a; },123);
std::cout<<"fr()="<<fr()<<std::end;

如上:函数输出值为:123最后,以一个lambda的例子结束本文:


#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
int main()
{
std::vector<int> c { 1,2,3,4,5,6,7 };
int x = 5;
    c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; } ), c.end());
std::cout << "c: ";
for (auto i: c) {
std::cout << i << ' ';
    }
std::cout << '\n';
// the type of a closure cannot be named, but can be inferred with auto
auto func1 = [](int i) { return i+4; };
std::cout << "func1: " << func1(6) << '\n';
// like all callable objects, closures can be captured in std::function
// (this may incur unnecessary overhead)
std::function<int(int)> func2 = [](int i) { return i+4; };
std::cout << "func2: " << func2(6) << '\n'; 
}

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8