目 录CONTENT

文章目录

C++ STL:lambda表达式

TalentQ
2025-08-27 / 0 评论 / 0 点赞 / 5 阅读 / 0 字

引言

随着C++11标准的发布,Lambda表达式成为了C++语言的重要特性之一。它极大地提高了代码的简洁性和灵活性,尤其在STL(标准模板库)算法中表现突出。

1 Lambda表达式简介

Lambda表达式是一种轻量级的匿名函数,可以在需要函数对象的地方直接定义和使用。其基本语法如下:

[捕获列表](参数列表) -> 返回类型 {
  // 函数体
}

代码示例:

#include <iostream>

int main() {
  // 一个简单的Lambda表达式:无参数,打印信息
  auto hello = []() {
    std::cout << "Hello, Lambda!" << std::endl;
  };
  hello();
  return 0;
}

2 Lambda表达式的原理

Lambda表达式本质上是编译器自动生成的一个匿名类对象。它可以捕获周围作用域的变量,支持值捕获和引用捕获。

捕获列表详解:

  • []:不捕获任何变量

  • [=]:以值方式捕获所有外部变量

  • [&]:以引用方式捕获所有外部变量

  • [x]:以值方式捕获变量x

  • [&x]:以引用方式捕获变量x

  • [=, &y]:以值方式捕获所有变量,但y以引用方式捕获

代码示例:

#include <iostream>

int main() {
  int a = 10, b = 20;
  auto sum = [a, &b]() {
    // a以值捕获,b以引用捕获
    return a + b;
  };
  b = 30;
  std::cout << "sum: " << sum() << std::endl; // 输出:sum: 40
  return 0;
}

3 Lambda表达式在STL中的典型应用

3.1 与std::sort配合使用

传统方法:

bool compare(int a, int b) {
  return a > b;
}

std::sort(vec.begin(), vec.end(), compare);

Lambda方法:

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

int main() {
  std::vector<int> vec = {5, 2, 8, 1};

  // 使用Lambda表达式进行降序排序
  std::sort(vec.begin(), vec.end(), [](int a, int b) {
    return a > b;
  });

  for (int v : vec) {
    std::cout << v << " ";
  }
  std::cout << std::endl; // 输出:8 5 2 1
  return 0;
}

对比优势:

  • Lambda表达式无需额外定义函数,提高代码局部性和可读性。

  • 支持捕获外部变量,灵活定制排序逻辑。

3.2 与std::for_each配合使用

传统方法:

void print(int x) {
  std::cout << x << " ";
}

std::for_each(vec.begin(), vec.end(), print);

Lambda方法:

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

int main() {
  std::vector<int> vec = {1, 2, 3, 4};

  // 使用Lambda表达式遍历并打印
  std::for_each(vec.begin(), vec.end(), [](int x) {
    std::cout << x << " ";
  });
  std::cout << std::endl;
  return 0;
}

3.3 与std::find_if配合使用

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

int main() {
  std::vector<int> vec = {1, 2, 3, 4, 5};

  int threshold = 3;
  // 查找第一个大于threshold的元素
  auto it = std::find_if(vec.begin(), vec.end(),
                         [threshold](int x) { return x > threshold; });

  if (it != vec.end()) {
    std::cout << "First element > threshold: " << *it << std::endl;
  }
  return 0;
}

4 Lambda表达式的高级用法

4.1 可变参数与返回类型

#include <iostream>

int main() {
  // 显式指定返回类型
  auto divide = [](double a, double b) -> double {
    if (b == 0) return 0;
    return a / b;
  };
  std::cout << "8 / 2 = " << divide(8, 2) << std::endl;
  return 0;
}

4.2 可变性(mutable)

默认情况下,值捕获的变量在Lambda体内是只读的。如果需要修改,需加mutable关键字。

#include <iostream>

int main() {
  int counter = 0;
  auto increment = [counter]() mutable {
    counter++;
    return counter;
  };
  std::cout << increment() << std::endl; // 输出:1
  std::cout << increment() << std::endl; // 输出:2
  std::cout << "外部counter: " << counter << std::endl; // 输出:外部counter: 0
  return 0;
}

5 与传统方法对比

方法

优点

缺点

普通函数

编译期类型安全,易复用

代码分散、难以捕获外部变量

函数对象

可保存状态,灵活

需额外定义类,代码复杂

Lambda表达式

简洁、灵活、易于捕获外部变量

过度嵌套时可读性下降

6 适用场景

  1. 局部性强的函数逻辑:如排序、查找、遍历等STL算法。

  2. 需要捕获外部变量:如动态条件、状态计数等。

  3. 简化代码结构:避免频繁定义函数对象类或全局函数。

7 扩展:Lambda表达式与并发

Lambda表达式也常用于C++并发库(如std::thread),提高线程函数的编写灵活性。

#include <thread>
#include <iostream>

int main() {
  int x = 10;
  std::thread t([x]() {
    std::cout << "Thread value: " << x << std::endl;
  });
  t.join();
  return 0;
}

0

评论区