编程语言不断发展,甚至像 C++ 这样很久以前就确立了自己的语言。他们向标准库添加功能并进行其他更改以简化程序员在动态领域工作的工作。
作为语言演变带来的更新的一部分,C++ 在其 2011 版本中增加了对 lambda 表达式的支持。
什么是 lambda 表达式,作为 C++ 程序员,您如何利用它来发挥自己的优势?
什么是 Lambda 表达式?
lambda 表达式也称为 lambda 函数。它是一个内联表达式,能够接受参数、执行操作和返回值,就像典型的函数一样。
您可以在另一个函数中使用 lambda 并将其分配给变量。Lamba 函数是在程序中定义匿名函数对象的一种实用方法。几乎每种语言都支持 lambda,尽管每种实现都各不相同。
C++ Lambda 表达式有哪些部分?
Lambda 表达式在 C++ 中很容易使用。您可以在 C++ 中分解 lambda 表达式的语法,如下所示:
[capture_clause](parameters) options { expression_body; }
例如:
int val = 13;
auto sumPlusVal = [val](int a, int b) mutable noexcept ->int { return val + a + b ; };
sumPlusVal(2, 5); // 20
这段代码声明了sumPlusVal变量 auto,因为 lambda 表达式可以接受和返回任何数据类型。这让编译器在编译期间确定类型。
从上面的代码中,您可以看到一个 lambda 表达式包含几个部分,这些部分指定了它的操作方式。以下是每个组件的快速概述。
- 捕获子句(Capture Clause):这是 lambda 表达式的第一部分,您可以在其中指定预先存在的变量或定义要在表达式主体中使用的新变量。有不同的方法来指定捕获,例如:
auto addTwo = [foo](){ return foo + 2; }; // by value
auto addThree = [&bar](){ return bar + 3; }; // by reference
auto addAllVal = [=](){ return foo + bar; }; // all by value
auto addAllRef = [&](){ return foo + bar; }; // all by reference
// create a variable in capture clause
auto createVarInCapture = [fooBar = foo + bar](){ return fooBar * 5; };
// no capture - returns error because foo is not accessible
auto errorExpression = [](){ return foo + 2; };
- 参数(Parameters):这部分 lambda 表达式也是可选的。它包含 lambda 所需的函数参数。这与您在 C++ 中定义函数参数的通常方式没有任何不同。
- 选项(Options):您还可以在定义 lambda 表达式时指定选项。您可以使用的一些选项是:mutable、exception(例如第一个示例代码中的noexcept )、 ->return_type(例如->int)、requires、attributes等。经常使用mutable选项,因为它允许在内部修改捕获拉姆达。下面的代码演示了这一点。
int value = 10;
// returns an error - value is a const inside the expression
auto decrement = [value](){ return --value; };
auto increment = [value]() mutable { return ++value; };
increment(); // 11
- 尽管其他选项很少使用,但您可以在cppreference.com的 lambdas 页面上获得有关它们的更多信息。
- 表达式主体(Expression body):这是 lambda 表达式的主体,它执行并返回一个值,就像函数一样。如有必要,您可以将 lambda 表达式的主体拆分为多行。但是,最好的做法是尽可能简短,以防止代码混乱。
Lambda 表达式有什么好处?
在代码中使用 lambda 函数有很多优点。除了提高开发速度和效率之外,您从 lambdas 获得的最大好处如下:
- Lambda 表达式有助于保持代码整洁。保持代码简单整洁的最佳方法之一是尽可能使用 lambda。这对于维护可读和可重用的代码结构非常有帮助。
- 您可以将 lambdas 作为参数传递给其他函数。C++ 标准库的 std::sort() 方法利用了这一优势。您可以将 lambda 作为此方法的参数之一传递,以指定函数应如何执行排序。例如:
std::vector<int> arr = {2, 5, 1, 3, 4};
std::sort(arr.begin(), arr.end(), [](int a, int b){ return a < b; });
// arr = {1, 2, 3, 4, 5}
- Lambda 是可重用的。有时,您可能希望在程序中的函数范围内使代码块可重用,而不必定义新函数。在这种情况下,Lambda 非常有用。考虑以下可重用 lambda 表达式的示例:
using namespace std;
int main() {
// define a reusable lambda
auto addUp = [](auto a, auto b, auto c) noexcept {
cout << "Now adding up... " << a << ", " << b << " and " << c << endl;
return a + b + c ;
};
cout << addUp(22, 33, 44) << endl;
cout << addUp(string("Happy "), string("Birth"), string("day")) << endl;
cout << addUp(true, false, true) << std::endl; // executes as numbers(1 and 0)
}
该程序产生以下结果:
此示例演示了定义 lambda 是多么简单,以便您可以将其与任何类型一起使用。
在 C++ 中使用 Lambda
lambda 表达式还有许多其他好处,随着程序结构变得越来越复杂,您会发现它们。事实上,C++ 程序员有时将 lambda 表达式称为闭包,因为它们是在代码中实现闭包的好方法。
如果要将现代 C++ 概念合并到代码库中,则应考虑使用 lambda 表达式。