1 语法

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

[ captures ] ( params ) specifiers exception attr -> ret { body }    (1)
[ captures ] ( params ) -> ret { body } (2)
[ captures ] ( params ) { body } (3)
[ captures ] { body } (4)
  • 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 带参数列表的匿名函数

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

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

[] -> double{
return 42;
}

等价于

[]{
return 42;
}

如果不指定返回类型,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;

输出

x:0
y:77
x:0
y:78
final 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;

输出

x:0
y:42
x:0
y:42
final 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;

输出

x:77
y:77
x:78
y:78
final x: 79
final y: 79

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

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

输出:

total:15

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

struct Point{
double x,y;
Point(){
x = (rand() % 10000) - 5000;
y = (rand() % 10000) - 5000;
} void Print(){
std::cout<<"["<<x<<","<<y<<"]"<<std::endl;
}
}; int count = 10;
std::vector<Point> points;
for( auto i = 0; i < 10 ; i++ ) points.push_back(Point()); cout<<"Unsorted:"<<endl;
for( auto i = 0; i < 10 ; i++ ) points[i].Print(); std::sort(points.begin(), points.end(),
[](const Point& a, const Point& b) -> bool{
return (a.x * a.x) + (a.y * a.y) < (b.x * b.x) + (b.y * b.y);
});
cout<<"Sorted:"<<endl;
for( auto i = 0; i < 10 ; i++ ) points[i].Print();

输出:

Unsorted:
[4383,-4114]
[-2223,1915]
[2793,3335]
[386,-4508]
[1649,-3579]
[-2638,-4973]
[3690,-4941]
[2763,-1074]
[-4460,-1574]
[4172,736]
Sorted:
[-2223,1915]
[2763,-1074]
[1649,-3579]
[4172,736]
[2793,3335]
[386,-4508]
[-4460,-1574]
[-2638,-4973]
[4383,-4114]
[3690,-4941]

2.7 返回匿名函数类型

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

2.8 奇怪的捕获变量作用域

void PerformOperation( function<void()> f ){
f();
} int main(){
int x = 100;
auto func = [&](){ x++;};
PerformOperation(func);
std::cout<< "x:" << x << std::endl;
return 0;
}

输出:

x:101

C++11 带来的新特性 (4)—— 匿名函数(Lambdas)的更多相关文章

  1. C++11 带来的新特性 (3)—— 关键字noexcept

    1 关键字noexcept 从C++11开始,我们能看到很多代码当中都有关键字noexcept.比如下面就是std::initializer_list的默认构造函数,其中使用了noexcept. co ...

  2. C++11 带来的新特性 (2)—— 统一初始化(Uniform Initialization)

    1 统一初始化(Uniform Initialization) 在C++ 11之前,所有对象的初始化方式是不同的,经常让写代码的我们感到困惑.C++ 11努力创造一个统一的初始化方式. 其语法是使用{ ...

  3. C++11 带来的新特性 (1)

    1 语法改进 1.1 模板表达式中的空格 在c++03 及以前 vector<list<int>>; //Error vector<list<int> > ...

  4. (数据科学学习手札139)geopandas 0.11版本重要新特性一览

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,就在几天前,geopandas ...

  5. C++11新特性:Lambda函数(匿名函数)

    声明:本文参考了Alex Allain的文章http://www.cprogramming.com/c++11/c++11-lambda-closures.html 加入了自己的理解,不是简单的翻译 ...

  6. Mysql8.0.11简介,新特性

    MySQL 8.0 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 注意:从 MySQL 5.7 升级到 MySQL 8 ...

  7. 发布倒计时!JDK11为我们带来哪些新特性?

    今年7月底,JDK11已经进入了Rampdown Phase Two阶段,这标志着该版本所有特性已经被冻结,不会有新的JEP会加入版本中. 这一阶段将会修复P1–P2级BUG,之后,JDK11预定于今 ...

  8. Git 2.7: 一个新的带来许多新特性和性能提升的主要版本

    在2.6版本发布两个月之后,Git 2.7发布.该版本带来了许多新特性以及性能的提升. 本文选取了Git 2.7带来的主要变化: git remote支持get-url子命令,可以显示指定远端的URL ...

  9. kafka 幂等生产者及事务(kafka0.11之后版本新特性)

    1. 幂等性设计1.1 引入目的生产者重复生产消息.生产者进行retry会产生重试时,会重复产生消息.有了幂等性之后,在进行retry重试时,只会生成一个消息. 1.2 幂等性实现1.2.1 PID ...

随机推荐

  1. (String) leetcode 67. Add Binary

    Given two binary strings, return their sum (also a binary string). The input strings are both non-em ...

  2. SpringBoot入门:Hello World

    1.Open IDEA,choose "New-->Project" 2.Choose "Spring Initializr" 3. Choose jav ...

  3. CDN-常用静态资源公共库

    js.css 等静态资源可以放在自己的服务器上,或者引用网络上的公共库使用(CDN) CDN 读取失败时从本地加载 <script src="https://code.jquery.c ...

  4. (Python)PO设计模式

    无规矩不成方圆.编写代码也是,如果没有大概的框架,管理代码将会是一件很头疼的事. 先看看笔者以前写的python脚本: 如果只有一个用例,这样看着好像挺整洁的.但是当用例越来越多后,如果元素定位发生了 ...

  5. weblogic找不到数据源

     查看weblogic日志 报错是每个数据源都找不到. 查看oracle用户状态 select username,account_status,lock_date from dba_users;  解 ...

  6. CentOS6和CentOS7

    http://mirrors.aliyun.com/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1708.iso net.ifnames= biosdevname ...

  7. 谈谈JAVA中的安全发布

    谈谈JAVA中的安全发布 昨天看到一篇文章阐述技术类资料的"等级",看完之后很有共鸣.再加上最近在工作中越发觉得线程安全性的重要性和难以捉摸,又掏出了<Java并发编程实战& ...

  8. SW:HTML DOM

    1:节点:nodeType,nodeValue,nodeName getAttributeNode() 方法从当前元素中通过名称获取属性节点. 元素节点nodeValue是null,属性节点nodeV ...

  9. 解决本地SqlServer无法连接远程服务器数据库,错误10060

    本地SqlServer 连不上服务器的数据库环境,错误信息如下图,折腾来折腾去,最终还是解决了 第一步 查看服务器本地端口是否已经打开,查看方法:首先向C:\Windows\System32文件夹添加 ...

  10. 全局API

    Vue.extend( options ): extend创建的是一个组件构造器,而不是一个具体的组件实例 //选项对象 baseOptions let baseOptions= { template ...