C++ Lambda 表达式是 C++11 引入的一个强大功能,允许你定义内联的匿名函数对象(也称为“Lambda 表达式”),使得代码更加简洁、灵活和易于维护。Lambda 表达式可以用在许多场景中,尤其是当你需要传递一个小的匿名函数到标准库算法或其他函数时。
1. 基本语法 Lambda 表达式的基本语法如下:
1 [捕获列表](参数列表) -> 返回类型 { 函数体 }
各部分说明:
捕获列表:决定 Lambda 函数是否可以访问外部作用域的变量,及如何访问它们(值捕获、引用捕获等)。
参数列表:定义 Lambda 函数的参数,就像普通的函数一样。
返回类型:指定 Lambda 表达式返回值的类型,如果省略,编译器会自动推导。
函数体:Lambda 函数的实现部分。
2. 示例代码 2.1 简单的 Lambda 表达式 1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> int main () { auto greet = []() { std::cout << "Hello, Lambda!" << std::endl; }; greet (); return 0 ; }
输出:
这里的 []()
表示一个没有参数并且没有捕获任何外部变量的 Lambda 函数。
2.2 带参数的 Lambda 表达式 1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> int main () { auto add = [](int a, int b) -> int { return a + b; }; std::cout << "Sum: " << add (5 , 3 ) << std::endl; return 0 ; }
在这个例子中,add 是一个带有两个 int 类型参数的 Lambda 表达式,返回两个整数的和。
2.3 捕获外部变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> int main () { int x = 5 ; int y = 10 ; auto sum = [x, y]() -> int { return x + y; }; std::cout << "Sum: " << sum () << std::endl; return 0 ; }
[x, y]
表示捕获 x 和 y,并按值捕获它们。如果你希望按引用捕获它们,可以使用 &
符号。
1 2 3 auto sum = [&x, &y]() -> int { return x + y; };
2.4 捕获所有外部变量
[=]
捕获所有外部变量,按值捕获。
[&]
捕获所有外部变量,按引用捕获。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> int main () { int a = 1 , b = 2 ; auto sum_by_value = [=]() -> int { return a + b; }; auto sum_by_ref = [&]() -> int { a = 10 ; return a + b; }; std::cout << "Sum by value: " << sum_by_value () << std::endl; std::cout << "Sum by ref: " << sum_by_ref () << std::endl; std::cout << "Modified a: " << a << std::endl; return 0 ; }
3. 返回类型的推导 C++11 中,Lambda 表达式的返回类型可以由编译器自动推导。你也可以显式地指定返回类型。
1 2 auto add = [](int a, int b) -> int { return a + b; }; auto add = [](int a, int b) { return a + b; };
如果 Lambda 函数有返回值,编译器会自动推导出返回类型。
如果你明确知道返回类型,最好显式地指定它,避免潜在的错误。
4. Lambda 表达式与标准库 Lambda 表达式常用于 C++ 标准库算法中,如 std::sort
、std::for_each
、std::transform
等。
4.1 示例:std::for_each 与 Lambda 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> #include <vector> #include <algorithm> int main () { std::vector<int > nums = {1 , 2 , 3 , 4 , 5 }; std::for_each(nums.begin (), nums.end (), [](int n) { std::cout << n << " " ; }); return 0 ; }
输出:
4.2 示例:std::sort 与 Lambda 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <iostream> #include <vector> #include <algorithm> int main () { std::vector<int > nums = {5 , 2 , 8 , 1 , 3 }; std::sort (nums.begin (), nums.end (), [](int a, int b) { return a < b; }); for (int num : nums) { std::cout << num << " " ; } return 0 ; }
输出:
5. 捕获列表的更多技巧 5.1 捕获所有变量并按引用捕获 1 2 3 4 5 6 7 int x = 5 , y = 10 ;auto f = [&]() { x++; y++; }; f ();std::cout << "x: " << x << ", y: " << y << std::endl;
5.2 捕获 this 指针(在类的成员函数中) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class MyClass {public : int value; MyClass (int v) : value (v) {} void printValue () { auto lambda = [this ]() { std::cout << "Value: " << value << std::endl; }; lambda (); } }; int main () { MyClass obj (42 ) ; obj.printValue (); }
6. 总结 Lambda 表达式提供了一种在函数内定义匿名函数的方式,可以捕获外部作用域的变量,具有高度的灵活性。它广泛应用于 C++11 及更高版本的标准库算法中,并且能够让代码更加简洁、可读和易于维护。
捕获外部变量:可以按值或引用捕获外部变量。
简洁的语法:允许在函数内部定义小型匿名函数。
与标准库配合使用:特别适用于像 std::sort
、std::for_each
等算法。