💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[一文带你认识 C++ 中的 Lambda 函数](https://mp.weixin.qq.com/s/W_6oaIRVh8qGxye1JzXgww) 闭包 自由变量 * lambda捕获列表(=传值、&传引用、this指针) ``` [&]( int a,int b){ a+b } ``` ***** > 【导读】:Lambda函数是 Modern C++在C++11中的一个体现 ,虽然在网络上已经有很多关于lambda函数的讨论或者教学,但是仍然有一部分内容(例如IIFE,lambda类型等)没人谈论。因此在这里,我不仅要向您展示C++中的lambda函数,而且还将介绍Lambda的工作原理以及发展。 以下是正文 * * * **什么是****lambda****函数?** 本文标题有点误导。因为 lambda并不总是函数指针,它一个表达式。但是为了简单起见,我一直都称它为函数。那么在本文中,我将会交替使用lambda函数和表达式来称呼。 Lambda函数是一段简短的代码片段,它具有以下特点: (1)不值得命名(无名,匿名,可处理等,无论您如何称呼) (2)不会重复使用 换句话说,它只是语法糖。lambda函数的语法定义为: ~~~ [ capture list ] (parameters) -> return-type ~~~ 通常, 编译器会评估lambda函数本身的返回类型。因此,我们不需要显式指定返回类型,即 -> return-type,但是在某些复杂的情况下,编译器无法推断出返回类型,此时我们需要指定返回类型。 **为什么要使用****lambda****函数?**  C++包括许多有用的通用函数,例如 std::for\_each,通常情况下方便了我们的使用。但是,当需要考虑特殊需求的时候,就比较头疼了。如下代码所示: ~~~ struct print ~~~ 如果您只在某个特定位置使用一次print,却写了一个类。这样的操作代价似乎太大了。 但是,对于这种情况,内联代码将更合适,并且可以通过如下的lambda函数来实现: ~~~ std::for_each(v.begin(), v.end(), [](int element) { cout <<element << endl; }); ~~~ **lambda****函数工作原理** ~~~ [&i] ( ) { std::cout << i; } ~~~ 如代码所示,编译器为每一个lambda函数生成独特的闭合。捕获列表将成为闭包中的构造函数参数,如果按值捕获,则会在闭包中创建相应类型的数据成员。此外,您可以在lambda函数参数中声明变量/对象,它将成为调用运算符的参数,即operator()。 **使用Lambda函数的好处** (1)零成本抽象。是的!  你没看错。lambda不会牺牲性能,运行速度和普通函数一样快。 (2)此外,代码会变得更加紧凑,结构层次更加明显和代码可读性更佳。 **学习****lambda****表达式** 1.通过引用/值捕获 ~~~ int main() ~~~ 输出: ~~~ main()::<lambda()> : 100 , 200 ~~~ 在上面的示例中,我在捕获列表中用到了 &。通过引用的方式捕获变量 x和 y。同样,= 表示按值捕获,这将在闭包内创建相同类型的数据成员,同时赋上相同的值。需要注意的是,参数列表是可选的, 如果不将参数传递给lambda表达式,则可以省略空括号。 2.Lambda捕获列表 2.1 将lambda作为参数传递 ~~~ template <typename Functor> ~~~ 输出: ~~~ Function Type : void f(Functor) [with Functor = main()::<lambda(int)>] ~~~ 您也可以将lambda函数作为参数传递给其他函数,就像我上面编写的普通函数一样。相信您注意到了,我在捕获列表中声明了变量i,它将成为数据成员。所以,每次调用lambda\_func时,它将被返回并递增。 2.2lambda捕获this指针或成员变量 ~~~ class Example ~~~ 捕获this指针也可以使用 \[this\], \[=\]或者 \[&\]。在上述任何情况下,类内数据成员(包括 private)的访问方式与常规方法一样。 可以看到lambda表达式的末尾,我多写了一个 ( ),该函数通常在声明之后立刻对其进行调用。它称为IIFE(立即调用函数表达式)。 **C++ lambda****函数类型** 1.通用lambda ~~~ const auto l = [](auto a, auto b, auto c) {}; ~~~ C++ 14中引入的通用lambda可以使用auto说明符。 2.可变参数通用λ ~~~ void print() {} ~~~ 具有可变参数的Lambda在许多情况下非常有用,例如调试,使用不同的数据输入重复操作等。 3.mutable lambda函数 通常,lambda的函数调用运算符是const-by-value,这意味着lambda需要捕获可变值的 关键字时,需要使用mutable关键字。 ~~~ []() mutable {} ~~~ 4.Lambda作为函数指针 ~~~ #include<iostream> ~~~ 您可以通过添加命令“+”来强制编译器将lambda生成为函数指针而不是闭包。 5.lambda函数作为返回值 ~~~ const auto less_than = [](auto x) { ~~~ 再进一步,lambda函数还可以返回另一个lambda函数。这也为代码的自定义性,代码可读性和紧凑性带来无限可能。 6.constexpr lambda表达式 从C ++ 17开始,可以将lambda表达式声明为constexpr。 ~~~ constexpr auto sum = [](const auto &a, const auto &b) { return a + b; }; ~~~ 即使你没有指定 constexpr,如果它恰好满足所有constexpr函数的要求,那么它也会被声明为constexpr。 **结束语** 希望您喜欢这篇文章。文中我使用几个简单的小例子来介绍关于lambda的大量复杂问题。考虑到代码的可表达性和易维护性,无论您想到什么,都应该使用lambda,就像可以在自定义删除器中将其用于智能指针和大多数STL算法一样。 https://hackernoon.com/all-about-lambda-functions-in-cfrom-c11-to-c17-2t1j32qw \- EOF -