C++11 带来的新特性 (4)—— 匿名函数(Lambdas)

1 语法

Lambdas并不是新概念,在其它语言中已经烂大街了。直接进入主题,先看语法:

1[ captures ] ( params ) specifiers exception attr -> ret { body } (1) 2[ captures ] ( params ) -> ret { body } (2) 3[ captures ] ( params ) { body } (3) 4[ captures ] { body } (4) 5
  • captures:捕获参数。详细格式见下图。

格式

意义

[]

默认不捕获任何变量

[=]

默认以值捕获所有变量

[&]

默认以引用捕获所有变量

[x]

仅以值捕获x,其它变量不捕获

[&x]

仅以引用捕获x,其它变量不捕获

[=, &x]

默认以值捕获所有变量,但是x是例外,通过引用捕获

[&, x]

默认以引用捕获所有变量,但是x是例外,通过值捕获

[this]

通过引用捕获当前对象(其实是复制指针)

[*this]

通过传值方式捕获当前对象

  • params:参数列表。
  • ret:返回类型。
  • body:函数体。
  • specifiers:限定符列表。比如mutable。
  • exception:异常规定。比如noexcept。
  • attr:属性规定,详见

2 使用

Lambdas重在使用,所以下面直接上实例,由浅入深的介绍使用方法。

2.1 打印字符串

  • 定义一个匿名函数

    []{ std::cout<< "hello world!" <<std::endl; }

  • 调用匿名函数

    []{ std::cout<< "hello world!" <<std::endl; }();

  • 传递匿名函数给一个变量

    auto l = []{ std::cout<< "hello world!" <<std::endl; }; l();

2.2 带参数列表的匿名函数

1auto l = [](const std::string &s){ 2 std::cout<< s <<std::endl; 3}; 4l("hello world!");

2.3 指定返回值类型的匿名函数

1[] -> double{ 2 return 42; 3}

等价于

1[]{ 2 return 42; 3}

如果不指定返回类型,C++11也可以自动推断类型。

2.4 带捕获参数的匿名函数

  • 捕获变量值+捕获变量引用

    int x = 0; int y = 42; auto f = [x, &y] { std::cout<<"x:" << x << std::endl; std::cout<<"y:" << y << std::endl; ++y; //++x;//Error }; x = y = 77; f(); f(); std::cout<< "final y: " << y <<std::endl;

输出

1x:0 2y:77 3x:0 4y:78 5final y: 79
  • 捕获所有变量值

    int x = 0; int y = 42; auto f = [=] { std::cout<<"x:" << x << std::endl; std::cout<<"y:" << y << std::endl; //++y;//Error //++x;//Error }; x = y = 77; f(); f(); std::cout<< "final y: " << y <<std::endl;

输出

1x:0 2y:42 3x:0 4y:42 5final y: 77
  • 捕获所有变量引用

    int x = 0; int y = 42; auto f = [&] { std::cout<<"x:" << x << std::endl; std::cout<<"y:" << y << std::endl; ++y;//Error ++x;//Error }; x = y = 77; f(); f(); std::cout<< "final x: " << x <<std::endl; std::cout<< "final y: " << y <<std::endl;

输出

1x:77 2y:77 3x:78 4y:78 5final x: 79 6final y: 79

2.5 使用匿名函数统计容器中所有元素的值之和

1std::vector<int> vec = { 1, 2, 3, 4, 5 }; 2double total = 0; 3 4//inclucde 'algorithm' for foreach 5std::foreach(begin(vec), end(vec), 6 [&](int x) { 7 total += x; 8 }); 9std::cout<<"total:"<< total <<std::endl;

输出:

total:15

2.6 使用匿名函数对容器中的元素排序

1struct Point{ 2 double x,y; 3 Point(){ 4 x = (rand() % 10000) - 5000; 5 y = (rand() % 10000) - 5000; 6 } 7 8 void Print(){ 9 std::cout<<"["<<x<<","<<y<<"]"<<std::endl; 10 } 11}; 12 13 14int count = 10; 15std::vector<Point> points; 16for( auto i = 0; i < 10 ; i++ ) points.push_back(Point()); 17 18cout<<"Unsorted:"<<endl; 19for( auto i = 0; i < 10 ; i++ ) points[i].Print(); 20 21std::sort(points.begin(), points.end(), 22 [](const Point& a, const Point& b) -> bool{ 23 return (a.x * a.x) + (a.y * a.y) < (b.x * b.x) + (b.y * b.y); 24 }); 25cout<<"Sorted:"<<endl; 26for( auto i = 0; i < 10 ; i++ ) points[i].Print();

输出:

1Unsorted: 2[4383,-4114] 3[-2223,1915] 4[2793,3335] 5[386,-4508] 6[1649,-3579] 7[-2638,-4973] 8[3690,-4941] 9[2763,-1074] 10[-4460,-1574] 11[4172,736] 12Sorted: 13[-2223,1915] 14[2763,-1074] 15[1649,-3579] 16[4172,736] 17[2793,3335] 18[386,-4508] 19[-4460,-1574] 20[-2638,-4973] 21[4383,-4114] 22[3690,-4941]

2.7 返回匿名函数类型

1//include<functional> 2std::function<int(int,int)> returnLambda (){ 3 return [](int x, int y){ 4 return x*y; 5 }; 6} 7 8auto lf = returnLambda(); 9std::cout<< lf(6,7) << std::endl;

2.8 奇怪的捕获变量作用域

1void PerformOperation( function<void()> f ){ 2 f(); 3} 4 5int main(){ 6 int x = 100; 7 auto func = [&](){ x++;}; 8 PerformOperation(func); 9 std::cout<< "x:" << x << std::endl; 10 return 0; 11}

输出:

x:101
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

C++11 带来的新特性 (4)—— 匿名函数(Lambdas) - HelloWorld