C++——Lambda表达式

在C++中,Lambda表达式是一种匿名函数对象,它允许你在代码中直接定义一个函数,而不需要提前声明一个单独的函数。Lambda表达式是从C++11标准开始引入的,它极大地增强了C++语言的灵活性和表达能力,尤其在处理函数对象、回调函数以及与标准库中算法配合使用时非常方便。

基本语法:

cpp 复制代码
[捕获列表](参数列表) -> 返回类型{
    函数体
    //可以使用捕获列表中的变量
    return expression; //可选的返回语句
}
  • 捕获列表 :用于捕获当前作用域中的变量。捕获方式可以是值捕获([x])或引用捕获([&x])。也可以捕获所有变量([=]表示按值捕获所有变量,[&]表示按引用捕获所有变量)。

  • 参数列表:与普通函数的参数列表类似,可以为空。

  • 返回值类型 :可以显式指定,也可以省略(如果函数体中只有一条return语句,编译器会自动推导返回值类型)。

  • 函数体:包含具体的逻辑代码。

例如我们写一个两个数相加的lambda表达式:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main() {
	int x = 50;
	int y = 20;
	auto add=[](int a,int b)->int {
		return a + b;
		};
	int ret = add(x, y);
	cout << ret << endl;


	return 0;
}

Lambda表达式的使用场景:

作为函数对象:

Lambda表达式可以替代传统的函数对象(如std::function或自定义的类)。例如:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    // 使用Lambda表达式作为回调函数
    std::for_each(vec.begin(), vec.end(), [](int x) {
        std::cout << x << " ";
    });
    return 0;
}

在这个例子中,[](int x) { std::cout << x << " "; }是一个Lambda表达式,它被用作std::for_each的回调函数。

捕获变量

Lambda表达式可以捕获当前作用域中的变量。例如:

cpp 复制代码
#include <iostream>

int main() {
    int a = 10;
    int b = 20;
    // 按值捕获a,按引用捕获b
    auto lambda = [a, &b]() {
        std::cout << "a = " << a << ", b = " << b << std::endl;
        b = 30; // 修改b的值
    };
    lambda();
    std::cout << "b = " << b << std::endl; // 输出修改后的b
    return 0;
}

在这个例子中,a是按值捕获的,b是按引用捕获的。Lambda表达式内部可以访问和修改b的值。

与标准库算法结合

Lambda表达式与标准库中的算法(如std::sortstd::find_if等)配合使用非常方便。例如:

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {5, 2, 9, 1, 5, 6};
    // 使用Lambda表达式作为比较函数
    std::sort(vec.begin(), vec.end(), [](int a, int b) {
        return a > b; // 降序排序
    });
    for (int x : vec) {
        std::cout << x << " ";
    }
    return 0;
}

在这个例子中,Lambda表达式[](int a, int b) { return a > b; }被用作std::sort的比较函数,实现了降序排序。

Lambda表达式的特性

  • 匿名性:Lambda表达式没有名字,因此不能像普通函数那样被直接调用多次。不过,可以通过变量来存储Lambda表达式,然后通过变量名调用。

  • 对象性 :Lambda表达式本质上是一个函数对象。它可以通过operator()被调用,就像普通函数一样。

  • 可捕获变量:Lambda表达式可以捕获当前作用域中的变量,这使得它可以在函数体中访问这些变量。

  • 类型推导 :如果Lambda表达式的函数体中只有一条return语句,编译器可以自动推导返回值类型,无需显式指定。

Lambda表达式的限制

  • 捕获的变量不能重新赋值:如果捕获的变量是按值捕获的,那么在Lambda表达式中不能重新赋值。

  • Lambda表达式不能递归调用:由于Lambda表达式没有名字,因此无法直接在函数体中递归调用自己。不过,可以通过其他方式(如通过变量名)实现递归。

相关推荐
fouryears_234172 小时前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
我好喜欢你~2 小时前
C#---StopWatch类
开发语言·c#
lifallen3 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研3 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
快乐的划水a4 小时前
组合模式及优化
c++·设计模式·组合模式
cui__OaO5 小时前
Linux软件编程--线程
linux·开发语言·线程·互斥锁·死锁·信号量·嵌入式学习
星星火柴9365 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
鱼鱼说测试5 小时前
Jenkins+Python自动化持续集成详细教程
开发语言·servlet·php
艾莉丝努力练剑6 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
CHEN5_026 小时前
【Java基础面试题】Java基础概念
java·开发语言