c++Lambda表达式

Lambda 表达式是C++11引入的一个重要特性,它允许你在代码中定义匿名函数。

基本语法

[capture](parameters) -> return_type { body }

各部分说明

1. 捕获列表 [capture]

  • [] - 不捕获任何变量
  • [x] - 按值捕获变量 x
  • [&x] - 按引用捕获变量 x
  • [=] - 按值捕获所有外部变量
  • [&] - 按引用捕获所有外部变量
  • [=, &x] - 按值捕获所有变量,但 x 按引用捕获
  • [&, x] - 按引用捕获所有变量,但 x 按值捕获

2. 参数列表 (parameters)

类似于普通函数的参数列表

3. 返回类型 -> return_type

可选,编译器可以自动推导

4. 函数体 { body }

Lambda 的具体实现

基本例子

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 最简单的 lambda
    auto simple = []() { 
        std::cout << "Hello Lambda!" << std::endl; 
    };
    simple();  // 调用
    
    // 带参数的 lambda
    auto add = [](int a, int b) -> int { 
        return a + b; 
    };
    std::cout << add(3, 4) << std::endl;  // 7
    
    // 自动推导返回类型
    auto multiply = [](int a, int b) { 
        return a * b; 
    };
    std::cout << multiply(3, 4) << std::endl;  // 12
    
    return 0;
}

捕获列表详解

int x = 10;
int y = 20;

// 不捕获任何变量
auto lambda1 = []() { 
    // std::cout << x << std::endl;  // 错误!无法访问 x
};

// 按值捕获特定变量
auto lambda2 = [x]() { 
    std::cout << x << std::endl;  // 10,但不能修改 x
};

// 按引用捕获特定变量
auto lambda3 = [&x]() { 
    x = 100;  // 可以修改外部的 x
};

// 按值捕获所有变量
auto lambda4 = [=]() { 
    std::cout << x << " " << y << std::endl;  // 10 20
    // x = 50;  // 错误!按值捕获的变量默认是 const
};

// 按值捕获所有变量,但允许修改
auto lambda5 = [=]() mutable { 
    int temp = x;  // 可以修改局部副本
    temp = 50;
    std::cout << temp << std::endl;  // 50
};

// 按引用捕获所有变量
auto lambda6 = [&]() { 
    x = 100;  // 可以修改外部的 x
    y = 200;  // 可以修改外部的 y
};

// 混合捕获
auto lambda7 = [x, &y]() { 
    std::cout << x << std::endl;  // 按值捕获 x
    y = 300;                      // 按引用捕获 y,可以修改
};

实际应用场景

1. STL 算法中使用

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    
    // 查找第一个偶数
    auto it = std::find_if(numbers.begin(), numbers.end(), 
                          [](int n) { return n % 2 == 0; });
    
    // 排序(降序)
    std::sort(numbers.begin(), numbers.end(), 
              [](int a, int b) { return a > b; });
    
    // for_each 打印
    std::for_each(numbers.begin(), numbers.end(), 
                  [](int n) { std::cout << n << " "; });
    
    return 0;
}

2. 多线程中使用

#include <thread>
#include <iostream>

int main() {
    int data = 42;
    
    // Lambda 作为线程函数
    std::thread t([data]() {
        std::cout << "Thread data: " << data << std::endl;
    });
    
    t.join();
    
    // 更复杂的例子
    std::thread t2([data]() mutable {
        data += 10;
        std::cout << "Modified data: " << data << std::endl;  // 52
    });
    
    t2.join();
    
    return 0;
}

3. 回调函数

#include <functional>
#include <iostream>

void process_data(int value, std::function<void(int)> callback) {
    // 处理数据...
    int result = value * 2;
    callback(result);  // 调用回调函数
}

int main() {
    process_data(21, [](int result) {
        std::cout << "Result: " << result << std::endl;  // 42
    });
    
    return 0;
}

高级特性

1. 泛型 Lambda (C++14)

auto generic_lambda = [](auto x, auto y) {
    return x + y;
};

std::cout << generic_lambda(1, 2) << std::endl;      // 3
std::cout << generic_lambda(1.5, 2.5) << std::endl;  // 4.0

2. 初始化捕获 (C++14)

int x = 10;
auto lambda = [value = x * 2]() {  // 捕获并初始化
    std::cout << value << std::endl;  // 20
};

Lambda vs 普通函数 vs 函数对象

// 普通函数
int add_function(int a, int b) {
    return a + b;
}

// 函数对象
class Adder {
public:
    int operator()(int a, int b) const {
        return a + b;
    }
};

// Lambda
auto add_lambda = [](int a, int b) { 
    return a + b; 
};

// 使用方式相同
int result1 = add_function(3, 4);
int result2 = Adder()(3, 4);
int result3 = add_lambda(3, 4);
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐