最近更新于 2023-03-08 20:27

环境

Debian 11(arm64)

编译器 g++ 10.2.1;编译标准 C++20;参数:-std=c++20 -no-pie -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Werror=format-security -Wextra -pedantic -Wimplicit-fallthrough -Wsequence-point -Wswitch-unreachable -Wswitch-enum -Wstringop-truncation -Wbool-compare -Wtautological-compare -Wfloat-equal -Wshadow=global -Wpointer-arith -Wpointer-compare -Wcast-align -Wcast-qual -Wwrite-strings -Wdangling-else -Wlogical-op -Wconversion -g -O0

Lambda 表达式

Lambda 表达式可用于创建匿名函数对象

基本语法

[捕获列表](参数列表)->返回值{函数体}
  • 捕获列表用于访问外部变量
  • 参数列表用于指定参数,C++14 开始参数类型可以使用 auto,由编译器自动推导(泛型)
  • 返回值指定返回值类型,可以省略由编译器自动推导
  • 函数体进行功能实现
#include <iostream>

int main()
{
    // 指明了参数列表类型和返回值类型
    auto f1 = [](int num1, int num2)->int{return num1 + num2;};
    std::cout << f1(2, 8) << std::endl;

    // 自动推导参数列表类型(泛型)和返回值类型
    auto f2 = [](auto num1, auto num2){return num1 + num2;};
    std::cout << f2(2, 8) << std::endl;
    std::cout << f2(4.8, 3.2) << std::endl;

    // 捕获列表的使用
    int x = 10;
    int y = 5;
    auto f3 = [x, y](auto num1, auto num2){return (num1 + num2) * x * y;};
    std::cout << f3(2, 8) << std::endl;
}

file

用作函数对象

Lambda 可以传给函数或算法,作用类似函数对象

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

class Even
{
    public:
        bool operator()(int n)
        {
            return n % 2 == 0;
        }
};

int main()
{
    std::vector nums {1, 6, 4, 7, 9, 3, 8};

    // 函数对象
    auto count = std::count_if(nums.begin(), nums.end(), Even());
    std::cout << count << std::endl;

    // Lambda
    auto even = [](auto n){return n % 2 == 0;};
    count = std::count_if(nums.begin(), nums.end(), even);
    std::cout << count << std::endl;
}

file

用作返回值

#include <iostream>
#include <functional>

// 函数适配器
std::function<int(int)> f(int num1, int num2)
{
    return [num1, num2](int n){return (num1 + num2) * n;};
}

int main()
{
    auto f1 = f(4, 5);
    std::cout << f1(3) << std::endl; // (4 + 5) * 3

    auto f2 = f(1, 2);
    std::cout << f2(5) << std::endl; // (1 + 2) * 5
}