本文主要记录常见的lambda表达式的用法。
一 lambda表达式简介
lambda表达式是一个函数,但是它是一个匿名函数,也就是没有名称的函数。通常而言这种函数在代码中仅被调用一次,因此直接在函数内部定义它,以此来提高程序的逻辑性和可读性。
通常而言一个lambda函数展现为下面的形式
1
| [capture](parameters) mutable ->return-type{statement}
|
- [capture]:捕捉列表。捕捉列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数。捕捉列表能够捕捉上下文中的变量以供Lambda函数使用;
- (parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略;
- mutable:mutable修饰符,用来说用是否可以修改捕获的变量。默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空); 在值捕获时,加了mutable修饰符,才可以修改捕获变量。尽管可能在表达式的函数体中修改了捕获变量,但由于是值捕获(复制,拷贝),改变了的捕获变量,不影响捕获的变量;没加mutable修饰符时,不能修改;在引用捕获时,不管加不加mutable修饰符,都可以修改捕获变量,由于是引用捕获,原来的捕获变量也改变了。
- ->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。
- 如果function body中存在return语句,则该Lambda表达式的返回类型由return语句的返回类型确定;
- 如果function body中没有return语句,则返回值为void类型。
- {statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
二 简单的lambda表达式
1 2 3 4 5 6 7 8 9 10
| int main(){ [] {}(); }
void f(){ } int main(){ f(); }
|
1 2 3 4 5 6 7 8 9
| int main() { [] { cout << "Hello, World!"; }(); auto lam =[]() -> int { cout << "Hello, World!"; return 1; }; auto ret = lam(); auto lam2 =[]() -> string { cout << "Hello, World!"; return "test"; }; auto ret1 = lam2(); }
|
三 lambda表达式捕获变量功能
- [] 不捕获任何变量
- [&] 以引用方式捕获所有变量
- [=] 用值的方式捕获所有变量(可能被编译器优化为const &)
- [=, &foo] 以引用捕获foo, 但其余变量都靠值捕获
- [&, foo] 以值捕获foo, 但其余变量都靠引用捕获
- [bar] 以值方式捕获bar; 不捕获其它变量
- [this] 捕获所在类的this指针
1 2 3
| int a=1,b=2,c=3; auto lam2 =[&,a](){ cout << a<<b<<c<<endl;}; lam2();
|
1 2
| vector<string> address{"111","222",",333",".org","wwwtest.org"}; for_each(address.begin(),address.end(),[](string& str){cout<<str<<endl;});
|
四 使用function传递lambda表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> #include <functional> #include <string> void print(std::function<std::string ()> const &f){ std::cout<<f()<<std::endl; } int main() { std::cout << "Hello, World!" << std::endl; int num = 101; auto a = [&] () ->std::string { return std::to_string(num); }; print(a); num++; print(a); return 0; }
|