【C++】C++11 lambda表达式

0x00 前言

文章中的文字可能存在语法错误以及标点错误,请谅解;

如果在文章中发现代码错误或其它问题请告知,感谢!

0x01 lambda表达式的概念及声明

1.lambda概念

lambda表达式在C++11中被引用,其主要作用是可以不需要为一段逻辑代码而去专门命名一个函数名,并且可以捕获一定范围内的变量,可以方便定义和创建匿名函数,让程序具有更好的可读性和维护性。

2.lambda声明

lambda表达式的语法形式如下:

[capture list] (params list) mutable exception-> return type { function body }

capture list:捕获外部变量列表
params list:形参列表,类似普通函数中的参数
mutable:用来修饰值捕获的外部变量
exception:异常设定
return type:返回类型
function body:函数体

一个lambda表达式举例如下:

auto value = [](int input)->int{return ++input;};
std::cout << value (1) << std::endl; //输出2

该表达式表示不捕获任何外部变量,只将输入input自加1并返回。

有时候,当lambda返回值很明显可以则可以省略return type

auto value = [](int input){return ++input;};
std::cout << value (1) << std::endl; //输出2

我们可以省略某些lambda表达式某些部分来实现功能,常见的情况有以下几种:

常见形式解释
[capture list] (params list) -> return type {function body;};省略了用来修饰值捕获的外部变量,表示声明const类型表达式,不能修改捕获列表中的值
[capture list] (params list) {function body;};省略了返回值类型,但编译器可以根据funciton body中的return推断返回值类型,若没有return则返回值类型为void
[capture list] {function body;};省略了参数列表,可以看成无参函数

例如当lambda表达式没有形参列表时,可以省略params list,例如:

auto value1 = [](){return 1;};
auto value2 = []{return 1;};

0x02 lambda表达式捕获列表

lambda表达式可以通过捕获列表capture list获取指定范围内的变量:
[]:不捕获任何变量。
[&value]按引用捕获 value变量,同时不捕获其他变量。
[=value]按值捕获 value变量,同时不捕获其他变量。
[&]捕获外部作用域中所有变量,并作为引用在函数体function body中使用(按引用捕获)。
[=] 捕获外部作用域中所有变量,并作为副本在函数体function body中使用(按捕获)。
[=,&value]按值捕获外部作用域中所有变量,并按引用捕获 value变量。
[this] 捕获当前类中的 this 指针,让 lambda 表达式拥有和当前类成员函数同样的访问权限。如果已经使用了 & 或者 =,就默认添加此选项。捕获 this 的目的是可以在 lamda 中使用当前类的成员函数和成员变量。

举例:
例1:引用捕获

#include<iostream>
using namespace std;
int main()
{
    int value = 123;
    auto f = [&value] { cout << value << endl; }; 
    value = 321;
    f(); 
}

结果:

321

例2:值捕获

#include<iostream>
using namespace std;
int main()
{
    int value = 123;
    auto f = [=value] { cout << value << endl; }; 
    value = 321;
    f(); 
}

结果:

123

在这个例子中,lambda表达式按值捕获了所有外部变量,在捕获一瞬间,value的值就已经被复制到f中,之后value被修改,但是f中存储的值value仍然还是捕获时的值,因此结果输出时123。

例3:修改捕获变量

#include<iostream>
using namespace std;
int main()
{
    int value = 123;
    //auto f1 = [=](){ cout << ++value << endl; }; //报错,修改按值捕获的外部变量
    auto f2 = [=]()mutable { cout << ++value << endl; };

    f2(); 
}

结果:

124

例4:隐式捕获

#include<iostream>
using namespace std;
int main()
{
    int value = 123;
    auto f1 = [=] { cout << value << endl; }; 
    auto f2 = [&] { cout << value << endl; }; 
    value = 321;
    f1(); 
    f2();
}

结果:

123
321

例2例3中值捕获或引用捕获都需要确定需要捕获的变量,我们还可以让编译器根据函数体中的代码推断需要捕获哪些变量,该方式称为隐式捕获,[=]表示按值捕获方式捕获外部变量,[&]表示按引用捕获方式捕获外部变量。

0x03 lambda表达式实例

例5:从小到大排列

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool cmp(int a, int b)
{
    return  a < b;
}

int main()
{
    vector<int> vec{ 3, 2, 5, 7, 3, 2 };
    vector<int> lambdavec(vec);

    sort(vec.begin(), vec.end(), cmp); 
    cout << "common:" << endl;
    for (int it : vec)
        cout << it << ' ';
    cout << endl;

    sort(lambdavec.begin(), lambdavec.end(), [](int a, int b) -> bool { return a < b; });   // Lambda表达式
    cout << "lambda:" << endl;
    for (int it : lambdavec)
        cout << it << ' ';
}

结果:

common:
2 2 3 3 5 7 
lambda:
2 2 3 3 5 7 

以上。
参考文档:
1.http://c.biancheng.net/view/3741.html
2.https://www.cnblogs.com/DswCnblog/p/5629165.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值