讲解 C++ 匿名函数

匿名函数,也叫 Lambda 表达式,是 C++ 11 提出的特性,匿名函数能使得我们的程序更加灵活轻便。


基本语法

1
[capture](para) -> returnType { body }
  • capture :闭包
  • para :参数
  • returnType :返回类型
  • body :函数体

示例:

1
2
auto fun = [](int x, int y) { return x + y; };
std::cout << fun(1, 2) << '\n'; // 3
闭包

capture 称为闭包,作用是引用匿名函数体外的变量,其有如下格式:

1
2
3
4
5
6
7
8
[]						// 不引用外部变量,无法在函数体内使用外部变量
[x, &y] // x 按值捕获,y 按照引用捕获
[&] // 可以捕获所有外部变量,按照引用捕获
[=] // 可以捕获所有外部变量,按照值捕获
[&, x] // x 按照值捕获,其余所有变量按照引用捕获
[=, &y] // y 按照引用捕获,其余所有变量按照值捕获
[this] // 通过引用捕获当前对象
[*this] // 通过传值的方式捕获当前对象

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>

int main() {

int sum = 0;
std::vector<int> arr = {1, 2, 3, 4, 5};

auto fun = [&sum](int x) { sum += x; };
// auto fun = [sum](int x) { sum += x; }; 报错,sum 必须是可修改的左值,故只能通过引用的方式捕获

for (int x : arr) {
fun(x);
}

std::cout << sum << '\n'; // 15

return 0;
}

运用

匿名函数的运用十分灵活,以下我们举几个常见的例子:

  • STL 的排序函数中自定义排序方式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <iostream>
    #include <vector>
    #include <algorithm>

    struct Student {
    std::string name;
    int grade;
    };

    int main() {

    std::vector<Student> s_arr = {{"Jack", 99}, {"Alice", 97}, {"Bob", 83}, {"Carl", 100}, {"Clara", 66}};
    std::sort(s_arr.begin(), s_arr.end(), [](const Student& s1, const Student& s2) {
    return s1.grade > s2.grade;
    }); // 自定义学生成绩按照降序排序

    for (const auto& s : s_arr) {
    std::cout << s.name << ' ' << s.grade << '\n';
    }
    // Carl 100
    // Jack 99
    // Alice 97
    // Bob 83
    // Clara 66

    return 0;
    }

  • 定义一个匿名函数作为参数的函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <iostream>

    double solve(std::function<double(double)> fn, double left, double right, int n) {
    // 求一元函数在区间 [left, right] 的定积分
    double res = -fn(left) + fn(right);
    double d = (right - left) / n;
    for (int i = 0; i < n; i++) {
    res += 2 * fn(left + i * d) + 4 * fn(left + (i + 0.5) * d);
    }

    return d * res / 6;
    }

    int main() {

    std::cout << solve([](double x) { return x * x * x; }, 0, 1, 10) << '\n'; // 0.25

    return 0;
    }


讲解 C++ 匿名函数
https://goer17.github.io/2023/03/30/讲解 C++ 匿名函数/
作者
Captain_Lee
发布于
2023年3月30日
许可协议