YUKIPEDIA's blog

一个普通的XMUER

《Summer Pockets》久島鴎推し


Lambda表达式在STL中的应用

目录

  • C++中的Lambda表达式是一种简洁的方式来定义匿名函数,尤其在需要传递函数作为参数或局部定义函数时非常方便

  • Lambda表达式的语法格式如下:

    [capture](parameters) -> return_type {
        // function body
    };
    
    • capture:用于捕获外部变量,类似闭包。可以通过值传递或引用传递。
    • parameters:函数的参数列表(可以为空)。
    • return_type(可选):指定返回类型,若省略,编译器会自动推导。
    • function body:函数体,包含实际执行的代码。

    举个简单的例子:

    auto add = [](int a, int b) -> int {
        return a + b;
    };
    

    这个Lambda表达式创建了一个匿名函数,它接受两个整数参数ab,并返回它们的和。

  • 捕获外部变量:在Lambda表达式中可以通过捕获列表来引用函数外部的变量,有三种常见方式:

    1. 按值捕获 [x]:捕获外部变量x的值。

    2. 按引用捕获 [&x]:捕获外部变量x的引用,可以在Lambda内部修改它。

    3. 隐式捕获 [=](按值捕获所有外部变量)、[&](按引用捕获所有外部变量)。

    示例:

    int factor = 10;
    auto multiply = [factor](int x) { return x * factor; };  // 按值捕获
    
  • 常见用法

    1. 自定义比较器:在排序、优先队列等场合,通常需要根据特定规则对元素进行排序。

      • std::sort 自定义排序:
      vector<int> arr = {5, 2, 9, 1};
      sort(arr.begin(), arr.end(), [](int a, int b) {
          return a > b;  // 降序排列
      });
      
      • 优先队列(最大堆或最小堆):
      priority_queue<int, vector<int>, decltype([](int a, int b) { return a > b; })> pq;
      
    2. 函数对象作为参数传递:在STL算法函数中,Lambda常被用作传递的回调函数,比如std::for_each, std::count_if等。

      vector<int> arr = {1, 2, 3, 4, 5};
      int count = count_if(arr.begin(), arr.end(), [](int x) {
          return x % 2 == 0;  // 统计偶数
      });
      
    3. 简化DFS/BFS:在树或图的深度优先搜索、广度优先搜索中,可以通过Lambda表达式来嵌套递归函数,减少函数定义的复杂性。

      • 比如DFS查找树上的某个节点
      auto dfs = [&](auto&& self, int node, const vector<vector<int>>& tree) -> void {
          // 处理当前节点
          for (int neighbor : tree[node]) {
              self(self, neighbor, tree);  // 递归访问邻居节点
          }
      };