C++11:Lambda表达式

Posted 木大白易

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11:Lambda表达式相关的知识,希望对你有一定的参考价值。

声明

Lambda表达式完整的声明格式如下:

[capture list] (params list) mutable exception-> return type { function body }

各项具体含义如下

  • capture list:捕获外部变量列表
  • params list:形参列表
  • mutable指示符:用来说用是否可以修改捕获的变量
  • exception:异常设定
  • return type:返回类型
  • function body:函数体

但是并不是所有的项都必须写全,可以省略一些不需要的项,一般很少写exception。
比如:

  1. 如果不能修改捕获外部变量的值,则不需要写mutable指示符
[capture list] (params list) -> return type { function body }

[](int a)->bool {return a>1;}
  1. -> return type可以不写。如果function body里边有return,则返回return的返回值类型,如果没有return,则返回void
[capture list] (params list){ function body }

[](int a){return a>1;}
  1. 如果没有参数,则params list可以不写
[capture list]{ function body }

int a = 2;
[a]{return a>1;}//这里捕获外部变量

捕获外部变量

1、值捕获
值捕获和参数传递中的值传递类似,被捕获的变量的值在Lambda表达式创建时通过值拷贝的方式传入,因此随后对该变量的修改不会影响影响Lambda表达式中的值。
比如上边最后一个例子。

int a = 2;
auto m = [a]{return a>1;};
a=0;
cout << m() << endl;//这里输出为1

2、引用捕获
使用引用捕获一个外部变量,只需要在捕获列表变量前面加上一个引用说明符&

int a = 2;
auto m = [&a]{return a>1;};
a=0;
cout << m() << endl;//这里输出为0

3、隐式捕获
上面的值捕获和引用捕获都需要我们在捕获列表中显示列出Lambda表达式中使用的外部变量。除此之外,我们还可以让编译器根据函数体中的代码来推断需要捕获哪些变量,这种方式称之为隐式捕获。隐式捕获有两种方式,分别是[=][&][=]表示以值捕获的方式捕获外部变量,[&]表示以引用捕获的方式捕获外部变量。

int a = 2;
auto m = [=]{return a>1;};
a=0;
cout << m() << endl;//这里输出为1


a = 2;
auto n = [&a]{return a>1;};
a=0;
cout << n() << endl;//这里输出为0

总结:

捕获形式说明
[]不捕获任何外部变量
[变量名, …]默认以值得形式捕获指定的多个外部变量(用逗号分隔),如果引用捕获,需要显示声明(使用&说明符)
[this]以引用的形式捕获this指针
[*this]以值的形式捕获this指针
[=]以值的形式捕获所有外部变量
[&]以引用形式捕获所有外部变量
[=, &x]变量x以引用形式捕获,其余变量以传值形式捕获
[&, x]变量x以值的形式捕获,其余变量以引用形式捕获

修改捕获变量

前面我们提到过,在Lambda表达式中,如果以传值方式捕获外部变量,则函数体中不能修改该外部变量,否则会引发编译错误。那么有没有办法可以修改值捕获的外部变量呢?这是就需要使用mutable关键字,该关键字用以说明表达式体内的代码可以修改值捕获的变量,比如:

int a = 2;
auto m = [a] ()mutable { //注意这里有一个括号()
    a = -1;
    return a>1;
};
cout << m() << endl;//这里输出为0

表达式的参数

在Lambda表达式中传递参数还有一些限制,主要有以下几点:

  • 参数列表中不能有默认参数
  • 不支持可变参数
  • 所有参数必须有参数名

推荐阅读

C++ lambda表达式与函数对象
基础篇:Lambda 表达式和函数对象

以上是关于C++11:Lambda表达式的主要内容,如果未能解决你的问题,请参考以下文章

C++11——lambda表达式

什么是 C++11 中的 lambda 表达式?

[C++11]lambda表达式语法

IntelliJ:求值lambda表达式在调试时引发编译错误

c++中lambda表达式用法

c++中lambda表达式用法