Lambda 表达式

✅ 一、Lambda 是什么

一句话:

Lambda 表达式 = 轻量函数(匿名函数)

不需要声明名字、不需要单独写函数体,直接在代码里用。

✳ 二、C++ Lambda 基本格式

C++ 最完整语法:

capture(parameter_list) mutable noexcept -> return_type { body }

最常见精简格式:

\&(int x){ return x + 1; }

✳ 三、参数说明

部分 含义
[capture] 捕获外部变量
(parameter_list) 参数列表
mutable 允许修改捕获变量
return_type 返回类型
{ body } 实现代码

⚡ 四、捕获(capture)的写法重点

捕获方式决定 Lambda 能否访问外部变量

例1:按值捕获

int a = 10;

auto f = a() { return a + 1; };

例2:按引用捕获

int a = 10;

auto f = \&a() { a++; };

f();

执行后 a == 11

例3:全部按值捕获

=() { ... }

例4:全部按引用捕获

\&() { ... }

例5:混合捕获

=,\&x(){ ... }

🧰 五、典型使用场景

① 线程回调 / 异步执行

std::thread t(\[\]{

printf("worker\n");

});

t.join();
② STL 回调(最常用)

std::vector<int> v{1,2,3,4};

std::for_each(v.begin(), v.end(), \[\](int x){

std::cout << x << " ";

});
③ 排序自定义

std::sort(v.begin(), v.end(),

\[\](int a, int b){ return a > b; });

🔧 六、底层实现

C++ Lambda 本质是:

编译器生成一个匿名类(仿函数 functor)

int a = 10;

auto f = a() { return a+1; };

等价于:

struct _Lambda {

int a;

int operator()() const {

return a+1;

}

};

所以:

  • 捕获变量 → 编译器生成成员变量

  • 调用 → 通过 operator() 执行

这一点和 std::function / function pointer 不一样。

🚩 七、常见坑

❗ 1. 捕获值不会更新原变量

int a = 10;

auto f = a(){ return a++; };

f();

printf("%d\n", a); // 输出 10(不会变)

需要引用:

auto f = \&a(){ a++; };
❗ 2. 捕获 this

类内使用很常见:

auto f = this() { this->run(); };

🚀 八、和函数指针对比

函数指针 Lambda
是否捕获外部变量 ❌ 不行 ✔ 可以
创建方式 需要函数名 无名即可
内联优化 一般 强
易用性 差 好

高级用法:

1️⃣ 泛型 Lambda (C++14+)

允许参数类型自动推断:

auto add = \[\](auto a, auto b){ return a + b; };

add(1, 2); // int

add(1.5, 2.2); // double

add("a"s, "b"s); // string

2️⃣ 可变参数 Lambda (C++20)

auto print = \[\](auto... args){

(std::cout << ... << args) << "\n";

};

print(1, "hello", 3.14);

3️⃣ mutable 捕获值可修改

默认按值捕获是 const 的:

int x = 10;

auto f = x() mutable {

x++;

return x;

};

f(); // 11

4️⃣ 捕获 this 指针

类内非常常见:

auto f = this { doWork(); };

如果你写:

=

类内也隐式捕获 this

但 C++20 允许捕获 this 的副本(防悬垂):

auto f = \*this { doWork(); };

等于复制整个对象避免悬空指针。


5️⃣ 初始化捕获(C++14+重要能力)

auto f = val = std::move(bigObj) {

use(val);

};

变量 val 只存在 Lambda 内

特别适合智能指针:

auto f = p = std::make_shared\(5) {

std::cout << *p;

};

甚至可以这样:

auto f = i=0() mutable {

return ++i;

};

f(); //1

f(); //2

这种行为 = 闭包(closure)状态保持

6️⃣ constexpr Lambda(C++17+)

constexpr auto sqr = \[\](int x) { return x*x; };

static_assert(sqr(5) == 25);

还能在编译期算 Fibonacci:

constexpr auto fib = \[\](int n){

if (n <= 1) return n;

return fib(n-1) + fib(n-2);

};

7️⃣ 返回类型显式指定

当需要强制返回类型:

auto f = \[\](int x) -> double {

if(x > 0) return x;

return 0.5;

};

8️⃣ Lambda + std::function

⚠ 注意性能区别:

复制代码
std::function<int(int)> f = [](int x){ return x + 1; };

会发生:

  • 类型擦除

  • 动态分配(可能)

  • 低效

推荐保留 auto

auto f = [](int x){ return x+1; };

9️⃣ Lambda 做状态机(闭包)

比如计数器:

auto counter = i = 0() mutable {

return ++i;

};

counter(); //1

counter(); //2

counter(); //3

多线程共享状态:

auto sum = total = std::atomic\(0)(int x) mutable {

total += x;

};

这就是函数式闭包的力量。

🔟 Lambda 捕获移动对象

最重要的例子:线程池任务提交

pool.push(task=std::move(task)() mutable {

task();

});

⭐ 高级技巧加一条:模板 Lambda(C++20)

auto add = \[\]<typename T>(T a, T b){

return a + b;

};

⚙ 底层实现补充

Lambda 本质上:

编译器生成 struct + operator()

带捕获:

复制代码
int x = 10;
auto f = [x]{ return x+1; };
等价于

struct _lambda {

int x;

int operator()() const { return x+1; }

};

🚩 性能注意点

写法 性能
auto lambda 🟢 最快
template lambda 🟢 最快
std::function 🔴 可能动态分配,慢
bind 🔴 更慢/不推荐

🧨 STL 中的高阶组合

std::sort(v.begin(), v.end(),

\[\](auto &a, auto &b){

return a.score > b.score;

}

);

过滤:

auto it = std::remove_if(v.begin(), v.end(),

\&(auto &n){ return n < 0; });

相关推荐
xiaoye-duck9 分钟前
《C++ 项目:手写大模型接入 SDK》DeepSeek接口设计(上):初始化和全量响应
开发语言·网络·c++·语言模型
fpcc15 分钟前
跟我学c++中级篇—streambuf在glog中的应用分析
开发语言·c++
码匠许师傅26 分钟前
【C++三方组件】OpenCV:计算机视觉的事实标准
c++
C^h9 小时前
c++ string
开发语言·c++
raindayinrain10 小时前
c++高性能--原子操作,无锁编程,操作顺序
开发语言·c++·性能优化
学逆向的10 小时前
C++ 合并命名空间
开发语言·c++·网络安全
Zhao-Jichao10 小时前
VS2026 打包 C++ 程序生成 EXE,借助 Installer Project 扩展工具
开发语言·c++
小徐不徐说11 小时前
C++ 接口与插件设计:从工厂注册到 Qt 动态插件
数据库·c++·qt·系统架构·程序设计
大都督会赢的11 小时前
C++第一节课
开发语言·c++
UIU11411 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划