2022-11-26 20:25:21
C++11的lambda表达式是一种匿名函数特性,其基础语法为[捕获列表](参数列表) mutable -> 返回类型 {函数体},其中捕获列表和函数体为必需部分,其余可省略。捕获列表用于控制lambda对外部变量的访问方式,支持按值、按引用或混合捕获,修改值捕获的变量需使用mutable关键字。
一、基础语法结构lambda表达式的完整语法分为以下部分:
简化规则:
示例:
// 最简单的lambda:无参数、无捕获、返回42auto lambda1 = [] { return 42; };// 带参数的lambda:接收两个int参数,返回和auto lambda2 = [](int x, int y) { return x + y; };// 用于STL算法的lambda:降序排序std::vector<int> vec = {3, 1, 4};std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; });二、捕获列表详解捕获列表控制lambda对外部变量的访问方式,支持以下常见模式:
按值捕获:
[=]:捕获当前作用域所有局部变量(副本)。
[x]:仅按值捕获变量x。
特点:外部变量修改不影响lambda内的副本,lambda内修改副本不影响外部变量(除非使用mutable)。
按引用捕获:
[&]:捕获当前作用域所有局部变量(引用)。
[&x]:仅按引用捕获变量x。
特点:lambda内直接修改外部变量,需确保外部变量生命周期长于lambda。
混合捕获:
[=, &x]:按值捕获所有变量,但x按引用捕获。
[&, x]:按引用捕获所有变量,但x按值捕获。
捕获this指针:
[this]:捕获当前类的成员变量和函数(需确保lambda在对象生命周期内使用)。
示例:
int a = 10;int b = 20;// 按值捕获a,按引用捕获bauto f1 = [a, &b]() { a++; // 修改副本,外部a不变 b++; // 直接修改外部b};f1(); // 执行后:外部a=10,b=21// 修改按值捕获的变量需mutableint x = 5;auto f2 = [x]() mutable { x += 10; // 修改副本 std::cout << x; // 输出15};f2(); // 外部x仍为5三、特殊规则与注意事项示例:
int global_var = 100; // 全局变量,无需捕获auto f3 = [&]() { // 错误:global_var是全局变量,无需捕获 // 正确:直接使用即可 return global_var + 10;};// 显式指定返回类型auto f4 = [](double x) -> int { return static_cast<int>(x * 2);};四、应用场景示例:
// 使用lambda作为线程回调std::thread t([] { std::cout << "Hello from thread!" << std::endl;});t.join();// 结合条件变量使用lambdastd::mutex mtx;std::condition_variable cv;bool ready = false;auto waiter = [&] { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [&] { return ready; });};通过掌握基础语法和捕获规则,可以高效利用lambda表达式简化代码逻辑,尤其在需要灵活定义函数行为的场景中(如STL算法、多线程编程等)。