cpp_Lambda - ShenYj/ShenYj.github.io GitHub Wiki

Lambda表达式

简介

C11 新特性

  • 有点类似于 JavaScript 中的闭包、iOS中的 Block/Clourse,本质就是函数

  • 完整结构: [capture list] (params list) mutable exception -> return type { function body }

    • capture list:捕获外部变量列表
    • params list:形参列表,不能使用默认参数,不能省略参数名
    • mutable:用来说用是否可以修改捕获的变量
    • exception:异常设定
    • return type:返回值类型
    • function body:函数体
  • 有时可以省略部分结构

    • [capture list] (params list) -> return type {function body}
    • [capture list] (params list) { function body }
    • [capture list] { function body }

本质还是函数调用,只是省略一部分内容,并且限制了作用域

示例

void test() {

    /// 仅仅定义了一个没有名字的 Lambda 表达式, 不会被调用
    []{
        cout << "Lanbda 函数" << endl;
    ); 

    /// 调用了一个没有名字的 Lambda 表达式
    ([]{
        cout << "Lanbda 函数" << endl;
    })(); 
}

Lamdba 本身就是一个函数, 所以使用函数指针来接收, 也可以直接用 C++的 auto 关键字来简化

/// 定义
void (*p)() = []{
    cout << "Lanbda 函数" << endl;
);

/// 调用
p();

写法上接近于 c 的 block,区别是 block以 ^ 开头, 而 C++ 以 [] 开头

/// 有参数有返回值
int (*b)(int, int) = [](int a, int b) -> int { return a + b; };

b(1, 2);

作为函数参数

int exec(int v1, int v2, int(*func)(int, int)) {
    return func(v1, v2);
}

exec(20, 10, [](int a, int b) { return a + b });
exec(20, 10, [](int a, int b) { return a - b });
exec(20, 10, [](int a, int b) { return a * b });
exec(20, 10, [](int a, int b) { return a / b });

变量捕获

示例

int a = 10;
int b = 20;

/// 默认值捕获
auto func = [a, b]{
    cout << a << endl;
    cout << b << endl;
};

/// 地址捕获
auto func = [&a]{
    a++;    /// 因为是值捕获,允许修改外面的变量
    cout << a << endl;
};

/// 隐式捕获(值捕获)
auto func = [=]{
    cout << a << endl;
};


/// b是值捕获,其余变量地址捕获
auto func = [&, b]{
    cout << a << endl;
    cout << b << endl;
};

/// b是地址捕获,其余变量值捕获
auto func = [=, &b]{
    cout << a << endl;
    cout << b << endl;
};

/// 值捕获 + mutable 关键字
auto func = [a]() mutable {
    a++;                /// 不会改变外界 a 的值,修改的是内部变量 a
    cout << a << endl;  /// 输出结果 11
};

C++ 11 Lambda

对比 block

泛型Lambda表达式

c++ 11 开始提供的新特性 Lambda 表达式都是需要明确类型的,从 C++ 14 起支持泛型

就是将参数类型改为 auto

C++ 14 新特性 泛型Lambda表达式

  • 泛型 Lambda 表达式
auto func = [](auto v1, auto v2) { return v1 + v2 };
cout << func(10, 20.5) << endl;
  • 对捕获的变量进行初始化
/// 未初始化
int a;

auto func = [a = 10]() { /// 捕获的时候给了一个值
    cout << a << endl;
}

func();

/// 外界这里仍然是未初始化的
cout << a << endl;
⚠️ **GitHub.com Fallback** ⚠️