C++学习之路之lambda表达式

lambda表达式
eg.1

    int n = 5;int m = 3;
    auto fun1 = [&]<typename T>(T a, T b)mutable-> bool { return a +n > b + m;};
    cout << fun1(1,2)<< endl;

eg.1

	int x = 1; int y = 2;
	auto plus = [=] <typename T>(T a, T b) mutable -> int { x++; return x + y + a + b; };
	int c = plus(1, 2);

c++在c++11标准中引入了lambda表达式,一般用于定义匿名函数。lambda表达式与普通函数类似,也有参数列表、返回值类型和函数体,并且可以在函数内部定义。

eg.1

struct Item
{
    Item(int aa, int bb) : a(aa), b(bb) {} 
    int a;
    int b;
};
	
int main()
{
    std::vector<Item> vec;
    vec.push_back(Item(1, 19));
    vec.push_back(Item(10, 3));

    // 根据Item中成员a升序排序
    std::sort(vec.begin(), vec.end(),
        [] (const Item& v1, const Item& v2) { return v1.a < v2.a; });

    // 打印vec中的item成员
    std::for_each(vec.begin(), vec.end(),
        [] (const Item& item) { std::cout << item.a << " " << item.b << std::endl; });
	return 0;
}

在c++的官方文档中,给出了lamda表达式的写法。
官网:https://en.cppreference.com/w/cpp/language/lambda
在这里插入图片描述

[捕获列表]<模板参数列表>(参数列表)mutable -> int {代码}

捕获列表:

1. [] 什么也不捕获,无法lambda函数体使用任何
2. [=] 按值的方式捕获所有变量
3. [&] 按引用的方式捕获所有变量
4. [=, &a] 除了变量a之外,按值的方式捕获所有局部变量,变量a使用引用的方式来捕获。这里可以按引用捕获多个,例如 [=, &a, &b,&c]。这里注意,如果前面加了=,后面加的具体的参数必须以引用的方式来捕获,否则会报错。
5. [&, a] 除了变量a之外,按引用的方式捕获所有局部变量,变量a使用值的方式来捕获。这里后面的参数也可以多个,例如 [&, a, b, c]。这里注意,如果前面加了&,后面加的具体的参数必须以值的方式来捕获。
6. [a, &b] 以值的方式捕获a,引用的方式捕获b,也可以捕获多个。
7. [this] 在成员函数中,也可以直接捕获this指针,其实在成员函数中,[=][&]也会捕获this指针。

模板参数列表:用于模版

auto glambda = []<class T>(T a, auto&& b) { return a < b; };

mutable(可选):在函数内修改捕获的值,需要加上关键字 mutable。

int x = 1; int y = 2;
auto plus = [=] (int a, int b) mutable -> int { x++; return x + y + a + b; };
int c = plus(1, 2);

代码:大括号内为代码内容

int x = 1; int y = 2;
auto plus = [=] <typename T>(T a, T b) mutable -> int { x++; return x + y + a + b; };
int c = plus(1, 2);

lambda表达式各个成员的解释

  • captures 捕获列表,lambda可以把上下文变量以值或引用的方式捕获,在body中直接使用。
  • tparams 模板参数列表,让lambda可以像模板函数一样被调用。
  • params参数列表,有一点需要注意,在c++14之后允许使用auto左右参数类型。这里比较常用的参数就是mutable和exception。
  • trailing-return-type 返回值类型,一般可以省略掉,由编译器来推导。
  • body 函数体,函数的具体逻辑。

eg.2

#include <iostream>

int main()
{
    int a = 3;
    int b = 5;
    
    // 按值来捕获
    auto func1 = [a] { std::cout << a << std::endl; };
    func1();

    // 按值来捕获
    auto func2 = [=] { std::cout << a << " " << b << std::endl; };
    func2();

    // 按引用来捕获
    auto func3 = [&a] { std::cout << a << std::endl; };
    func3();

    // 按引用来捕获
    auto func4 = [&] { std::cout << a << " " << b << std::endl; };
    func4();
}

eg.3
引用捕获

int x = 1; int y = 2;
auto plus = [&] (int a, int b) -> int { x++; return x + y + a + b;};
int c = plus(1, 2);

eg.4

#include <iostream>
#include <thread>

using namespace std;

int main() {
  thread t([] {
    cout << "线程" << endl;
  });

  t.join();

  return 0;
}

[ captures ] ( params ) specs requires (optional) { body }

例如:
auto glambda = [](auto a, auto&& b) { return a < b; };

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值