C++11中lambda表达式
2016-09-05 11:50
218 查看
在C++11新标准中,lambda具有如下格式:
四个组成部分:
capture list: 捕获列表
parameter list: 参数列表
return type: 返回类型
function body: 执行代码。
具体的例子:
捕获列表
lambda中的捕获列表既可以捕获值,也可以捕获引用。
捕获值:
捕获引用:
隐式捕获可以捕获值、引用或者两者混合:
这里的f7使用的混合形式,可以读作“除了space捕获值之外,其他变量均捕获引用”。
可变 lambda
当lambda需要在其中修改被值捕获的变量的值时,需要给lambda加上mutable关键字。否则会有编译错误。
从输出中可以看出,space在lambda f8中的值,在第一次调用之后,就被变成了制表符Tab;但是在lambda之外,space仍然是空格。
返回类型
lambda的返回类型采用尾置返回类型的方式。一般的:
1)lambda如果只包含return语句,则编译器可以推断其返回类型,此时可以不显示指定返回类型;
2)否则,编译器假定lambda返回void,而返回void的函数不可以反悔任何具体值,这在大多数情况下是个矛盾,因此需要显示指定返回类型。
lambda代码块中有多个return语句,并且还有if/else语句,但是编译器可以根据return语句推断出,其返回值应该是一个int类型,所以可以省略尾置返回类型。
如下形式,由于编译器在推断返回类型时发现了不一致,所以必须显式的指定返回类型:
总结
1)lambda表达式形式: [capture list] (parameter list) -> return type { function body },其中parameter list和return type可以省略。
2)捕获列表可以捕获值[val],也可以捕获引用[&ref]。
3)捕获列表还可以隐式捕获局部变量,同样有捕获值[=]和捕获引用[&]两种方式,初次之外还可以混合捕获[&, val]或者[=, &ref]。
4)当lambda需要修改捕获的值时,需要加上mutable关键字。
5)当lambda无法自动推断出返回值类型时,需要通过尾置返回类型的方式显示指定。
[capture list] (parameter list) -> return type { function body }
四个组成部分:
capture list: 捕获列表
parameter list: 参数列表
return type: 返回类型
function body: 执行代码。
具体的例子:
auto f1 = [] { return 1; }; auto f2 = [] () { return 2; }; cout<<f1()<<'\t'<<f2()<<endl;
捕获列表
lambda中的捕获列表既可以捕获值,也可以捕获引用。
捕获值:
int test_data[] = {1, 5, 9, 7, 3, 19, 13, 17}; int border = 8; auto f3 = [border](const int &i){ if(i > border) cout<<i<<'\t'; }; for_each(begin(test_data), end(test_data), f3); cout<<endl;
捕获引用:
auto f4 = [&border](const int &i){ if(i > border) cout<<i<<'\t'; }; border = 6; for_each(begin(test_data), end(test_data), f4); cout<<endl;
隐式捕获可以捕获值、引用或者两者混合:
char space = ' '; auto f5 = [=](const int &i){ if(i > border) cout<<i<<'\t'; }; auto f6 = [&](const int &i){ if(i > border) cout<<i<<'\t'; }; auto f7 = [&, space](const int &i){ if(i > border) cout<<i<<space; }; border = 0; for_each(begin(test_data), end(test_data), f5); cout<<endl; for_each(begin(test_data), end(test_data), f6); cout<<endl; for_each(begin(test_data), end(test_data), f7); cout<<endl;
这里的f7使用的混合形式,可以读作“除了space捕获值之外,其他变量均捕获引用”。
可变 lambda
当lambda需要在其中修改被值捕获的变量的值时,需要给lambda加上mutable关键字。否则会有编译错误。
auto f8 = [&, space](const int &i) mutable { if(i > border) {cout<<i<<space; space='\t';} }; for_each(begin(test_data), end(test_data), f8); cout<<endl; cout<<1<<space<<2<<endl;
从输出中可以看出,space在lambda f8中的值,在第一次调用之后,就被变成了制表符Tab;但是在lambda之外,space仍然是空格。
返回类型
lambda的返回类型采用尾置返回类型的方式。一般的:
1)lambda如果只包含return语句,则编译器可以推断其返回类型,此时可以不显示指定返回类型;
2)否则,编译器假定lambda返回void,而返回void的函数不可以反悔任何具体值,这在大多数情况下是个矛盾,因此需要显示指定返回类型。
lambda代码块中有多个return语句,并且还有if/else语句,但是编译器可以根据return语句推断出,其返回值应该是一个int类型,所以可以省略尾置返回类型。
如下形式,由于编译器在推断返回类型时发现了不一致,所以必须显式的指定返回类型:
auto f10 = [](const int i) -> double {if(i % 5) return i * 5.0; else return i;}; transform(begin(test_data), end(test_data), begin(test_data), f10); for_each(begin(test_data), end(test_data), f6); cout<<endl;
总结
1)lambda表达式形式: [capture list] (parameter list) -> return type { function body },其中parameter list和return type可以省略。
2)捕获列表可以捕获值[val],也可以捕获引用[&ref]。
3)捕获列表还可以隐式捕获局部变量,同样有捕获值[=]和捕获引用[&]两种方式,初次之外还可以混合捕获[&, val]或者[=, &ref]。
4)当lambda需要修改捕获的值时,需要加上mutable关键字。
5)当lambda无法自动推断出返回值类型时,需要通过尾置返回类型的方式显示指定。
相关文章推荐
- [C++11] lambda表达式
- C++11 lambda表达式
- 【C++11新特性】 Lambda表达式
- C++11 Lambda表达式
- C++11 Lambda表达式简单解析
- c++11中的lambda表达式
- C++11中的匿名函数(lambda函数,lambda表达式)
- 浅谈C++11新引入的lambda表达式
- 每天进步一点点——C++11中使用lambda表达式实现一个简单的ScopeGuard
- C++11中的匿名函数(lambda函数,lambda表达式)
- c++11 lambda表达式
- C++11 在析构函数中执行lambda表达式(std::function)捕获this指针的陷阱
- (C++11)Lambda表达式(匿名函数)和为什么使用Lanbda表达式
- 一段关于c++11中lambda表达式和std::function的体验代码
- C++11--lambda表达式
- C++11中的Lambda表达式
- c++11的lambda表达式与传统的函数指针
- [C++11] Lambda表达式
- Cocos2d-x_C++11新特性Lambda表达式
- C++11 Lambda表达式(匿名函数)