C++ Lambda 表达式从入门到放弃

本文详细介绍了C++11中的Lambda表达式,包括其语法、参数捕获方式、操作符重载、mutable和exception声明以及返回类型。通过实例展示了Lambda如何简化函数对象的创建和使用,以及在值捕获和引用捕获中的区别。Lambda表达式在代码中可用于简化排序、迭代等操作,提高代码可读性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

总结记录自己学习并使用 C++ Lambda 表达式笔记。

Lambda 表达式概述

Lambda表达式是C++11新特性,用于创建匿名的函数对象,简化编程工作。

语法

[函数对象参数] (操作符重载函数参数)mutable或exception声明 ->返回类型{函数体}

其中返回值类型可隐式推导,void类型返回值可省略。
函数对象参数定义了Lambda如何访问作用域内的变量。

1. 函数对象参数

标示一个Lambda表达式的开始,必须存在,不能省略。函数参数对象只能使用那些定义 Lambda 所在作用范围内可见的局部变量(包含Lambda所在类的this)
a. []:没有任何函数参数对象
b. [=]:以值传递方式捕获Lambda所在范围内的所有局部变量。
c. [&]:以引用传递方法捕获Lambda所在范围内的所有局部变量。
d. this:函数体可以使用Lambda所在类的成员变量。
e. [x,&y]:x以值传递捕获,y以引用形式捕获。
f. [=,&z]:z以引用形式捕获,其他变量以值传递捕获。
g. [&,x]:x以值传递形式捕获,其他变量以引用形式捕获。

lambda要访问所在函数的局部变量时,必须先捕获。两种局部变量捕获方式:
值捕获:创建lambda表达式时,拷贝所在函数的局部变量的值。
引用捕获:创建lambda表达式时,获取变量的引用。需要确保lambda使用变量时,变量对应对象存在。
注:
1)值捕获是发生在lambda创建时,而非调用时。
2)lambda无法捕获任何static变量、全局变量,不过可以在lambda表达式内部直接访问。

#include <iostream>
using namespace std;

// 值捕获拷贝变量,发生在lambda创建时
void lambda_value()
{
    int v1 = 1024;
    auto a = [v1]()->int { return v1; }; // 值捕获v1 = 1024
    v1 = 0;
    auto b = a(); // lambda调用时,不会改变捕获值,因此b为1024
    cout<<b<<endl;
}

// 引用捕获获取变量引用
void lambda_reference()
{
    int v1 = 1024;
    auto a = [&v1]()->int { return v1; }; // 引用捕获v1
    v1 = 0;
    auto b = a(); // b为0
    cout<<b<<endl;
}

int main(int argc, const char * argv[])
{
    lambda_value();
    lambda_reference();
    return 0;
}

2. 操作符重载函数参数

参数列表,标识重载的()操作符,没有参数时,可以省略,但"()"不可用省略,类似于函数定义。参数可以使用值传递和引用传递。

3. mutable 或者 exception 声明

可以省略。函数参数按值传递时,加上mutable修饰后,可以修改传递进来的拷贝。exception声明用于指定函数抛出的异常,可以使用throw(int)。

void lambda_mutable()
{
    int v1 = 1023;
    auto f = [v1]() mutable { return ++v1; }; // 加上mutable才能修改值捕获的v1
    // <=> auto f = [v1]() mutable -> int { return ++v1; };
    v1 = 0;
    auto val = f(); // val 为1024
    cout<<val<<endl;
}

4. -> 返回值类型

标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方时,这部分可以省略,编译器自动推断返回类型。如果编译器无法推断lambda返回类型,就需要尾置返回类型,不可省略。

5. 函数体

标识函数的实现,不能省略,函数体可以为空。

简单例子

之前写过一篇 vector中pair的排序方法 的文章里面有用到 Lambda 表达式。
vector中pair的排序方法
下面同样给出一个类似的例子:

#include"iostream"
#include"vector"
#include"algorithm"
using namespace std;

static bool cmp(int &a, int &b)
{
	return a > b;
}

int main()
{
    vector<int> data;
    for(unsigned int i = 0; i < 10; i++) {
		data.push_back(i);
    }
	for(unsigned int i = 0; i < data.size(); ++i) {
        cout << data[i] << endl;
    }    
    //sort(data.begin(), data.end(), cmp);
	sort(data.begin(), data.end(), [](int &a,int &b)->bool { return a>b;});
    for_each(data.begin(), data.end(), [](int & d){ cout<<d<<endl;});
    return 0;
}

总结

熟能生巧, 多写多用。

参考网址

  1. cppreference.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值