Lambda表达式

Lambda表达式

Lambda 表达式(Lambda Expression)是 C++11 引入的一个“语法糖”,可以方便快捷地创建一个“函数对象”。

从 C++11 开始,C++ 有三种方式可以创建/传递一个可以被调用的对象:

  • 函数指针
  • 仿函数(Functor)
  • Lambda 表达式

函数指针

函数指针是从 C 语言老祖宗继承下来的东西,比较原始,功能也比较弱:

1、无法直接捕获当前的一些状态,所有外部状态只能通过参数传递(不考虑在函数内部使用 static 变量)。
2、使用函数指针的调用无法 inline(编译期无法确定这个指针会被赋上什么值)。

// 一个指向有两个整型参数,返回值为整型参数的函数指针类型
int (*)(int, int);

// 通常我们用 typedef 来定义函数指针类型的别名方便使用
typedef int (*Plus)(int, int);

// 从 C++11 开始,更推荐使用 using 来定义别名
using Plus = int (*)(int, int);

仿函数

仿函数其实就是让一个类(class/struct)的对象的使用看上去像一个函数,具体实现就是在类中实现 operator()比如:

class Plus {
 public:
  int operator()(int a, int b) {
    return a + b;
  }   
};

Plus plus; 
std::cout << plus(11, 22) << std::endl;   // 输出 33

相比函数指针,仿函数对象可通过成员变量来捕获/传递一些状态。缺点就是,写起来很麻烦

Lambda 表达式

Lambda 表达式在表达能力上和仿函数是等价的。编译器一般也是通过自动生成类似仿函数的代码来实现 Lambda 表达式的。上面的例子,用 Lambda 改写如下:

auto Plus = [](int a, int b) { return a + b; };

一个完整的 Lambda 表达式的组成如下:

[ capture-list ] ( params ) mutable(optional) -> ret(optional) { body } 
  • capture-list:捕获列表。前面的例子 auto Plus = [](int a, int b) { return a + b; }; 没有捕获任何变量
  • params:和普通函数一样的参数
  • mutable:只有这个 Lambda 表达式是 mutable 的才允许修改按值捕获的参数,不过修改的仍然是拷贝过来的值,不改变值的本体
  • ret:返回值类型,可以省略,让编译器通过 return 语句自动推导
  • body:函数的具体逻辑

Lambda表达式捕获列表(不建议直接使用 [&] 或 [=] 捕获所有参数):

  • [=] 函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)
  • [&] 函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)
  • [this] 函数体内可以使用Lambda所在类中的成员变量
  • [a] 将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符
  • [&a] 将a按引用进行传递
  • [=,&a, &b] 除a和b按引用进行传递外,其他参数都按值进行传递
  • [&, a, b] 除a和b按值进行传递外,其他参数都按引用进行传递

一些例子

auto function = [] (int first, int second){
    return first + second;
};
	
function(100, 200);
int index = 1;
int num = 100;
auto function = ([=]{
			std::cout << "index: "<< index << ", " 
                << "num: "<< num << std::endl;
	}
);

function();
#include <iostream>
using namespace std;
 
class Lambda {
public:
    void sayHello() {
        std::cout << "Hello" << std::endl;
    };

    void lambda() {
        auto function = [this]{ 
            this->sayHello(); 
        };

        function();
    }
};
 
int main()
{
    Lambda demo;
    demo.lambda();
}
posted @   Bdathe  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示