基本表达式

[capture](parameters) -> return-type {body}

当没有返回类型时, 可以省略 -> return-type

变量捕获与lambda闭包实现

  • [] 不截取任何变
  • [&] 截取外部作用域中所有变量,并作为引用在函数体中使用
  • [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
  • [=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
  • [bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
  • [x, &y] x按值传递,y按引用传递
  • [this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

lambda 的底层实现

lambda 其实是c++的语法糖,是通过c++编译器生成class来实现的,看一个简单的例子。

#include <functional>
using namespace std;

int main(int argc, char* argv[]) {
    int x = 0;
    int y = 0;
    int z = 0;
    auto func = [&](int a)->int{x+=a; y++; return x;};
    func(1);
  
    return 0;
}

通过cppinsights 站点来查看编译器的实现方法

#include <functional>
using namespace std;

int main(int argc, char** argv) {
    int x = 0;
    int y = 0;
    int z = 0;

    class __lambda_8_16 {
    public:
        inline /*constexpr */ int operator()(int a) const {
            x = x + a;
            y++;
            return x;
        }

    private:
        int& x;
        int& y;

    public:
        __lambda_8_16(int& _x, int& _y) : x{_x}, y{_y} {}
    };

    __lambda_8_16 func = __lambda_8_16{x, y};
    static_cast<const __lambda_8_16>(func).operator()(1);
    return 0;
}

匿名函数在编译器中生成了类 class __lambda_6_16,其中operator()中使用了x和y,参数是引用传参。