c++ lambda表达式基本语法为[捕获列表](参数列表)->返回类型{函数体},最简形式是[](){};捕获列表和返回类型可省略,编译器能自动推导返回类型。

lambda表达式怎么写,基本语法长什么样
C++ lambda 是一个可调用对象,不是函数指针,也不是普通函数;它本质是编译器生成的匿名类的实例。最简形式是 [capture](params) -> return_type { body },其中 capture 和 return_type 都可以省略。
常见写法示例:
auto f1 = []() { return 42; }; // 无捕获、无参数、自动推导返回类型
auto f2 = [&](int x) -> double { return x * 1.5; }; // 按引用捕获外部变量,显式声明返回类型
auto f3 = [x = 10, &y](auto z) { y += x + z; }; // 初始化捕获 + 引用捕获 + auto 参数
注意:省略 -> return_type 时,若函数体只有一条 return 语句,编译器能推导;否则返回类型为 void。
捕获列表常见错误和陷阱
捕获方式选错会导致未定义行为或编译失败。比如在异步回调中按值捕获大对象,或在 lambda 存活期超过局部变量时还按引用捕获。
-
[&]捕获所有外部变量为引用 —— 若 lambda 被存储(如放进std::function)并延后执行,而原作用域已退出,访问引用就是悬垂引用 -
[=]按值捕获所有变量 —— 对象会被拷贝(或移动),若对象不可拷贝(如std::unique_ptr),编译失败;若对象很大,可能带来意外开销 -
[x, &y]混合捕获 —— 必须先列值捕获,再列引用捕获;顺序不重要,但写错语法(如[&y, x])在某些老编译器会报错 -
[this]显式捕获当前对象 —— 在类成员函数中需要访问this->member时必须写,不能靠[=]或[&]自动包含this
lambda 能传给哪些标准库函数
绝大多数接受可调用对象的 STL 算法都支持 lambda,比如 std::sort、std::find_if、std::transform。但要注意:lambda 类型是唯一的、不可名状的,不能直接作为函数模板参数类型写出来(除非用 auto 或泛型 lambda)。
典型用法:
std::vector<int> v = {3, 1, 4, 1, 5};
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); // 降序
<p>int threshold = 10;
auto it = std::find_if(v.begin(), v.end(), [threshold](int x) { return x > threshold; });</p></int>
注意:std::function 可以装 lambda,但有类型擦除开销;如果只是临时传给算法,优先用 auto 或直接传递,避免不必要的包装。
泛型 lambda 怎么用,和普通模板函数区别在哪
C++14 起支持泛型 lambda,即参数类型用 auto 占位,编译器为每次调用实例化对应版本 —— 它本质上是闭包类的 operator() 是函数模板。
例如:
auto add = [](auto a, auto b) { return a + b; };
add(3, 4); // 实例化为 int+int
add(3.14, 2.7); // 实例化为 double+double
add(std::string{"a"}, "b"); // 实例化为 string+const char*
和普通函数模板不同的是:泛型 lambda 的捕获列表在定义时就固定了,不能随调用变化;而且它无法像模板函数那样显式指定模板参数(如 add<int double>(...)</int> 不合法)。
容易忽略的一点:泛型 lambda 体内若用了仅对部分类型有效的操作(比如 a / b),编译器会在调用时才报错,而不是定义时 —— 这让错误定位稍晚,也意味着要靠测试覆盖更多类型组合。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











