它演示提供 lambda 表达式的结构元素的示例,这些元素与示例。
选择 是可选的):
compound-statement
进一步失败的组件这些语法如下:
lambda-introducer:
选择
Visual Studio 支持 C++11 标准 Lambda 表达式语法及其所有 C++11 功能与除了 lambda,以下操作:
-
Rvalue References 节。
-
attribute-specifier-seq 不支持。
Visual Studio 向 C++11 lambda 功能通过添加以下功能:
-
无状态是 lambda omni 转换的任意函数使用调用约定的函数的指针。
-
{ return expression; } 复杂的主体的 lambda 自动返回这样的类型,只要所有返回语句具有相同的类型。(这在 C++14 标准现在建议的)。
Lambda 表达式的属性
下图将该语法映射到示例。
图中的标注如下所示:
-
lambda-introducer(在本主题的后面称为“capture 子句”)
-
lambda declarator(在本主题的后面称为“参数列表”)
-
mutable(在本主题的后面称为“可变规范”)
-
exception-specification(在本主题的后面称为“异常规范”)
-
trailing-return-type(在本主题的后面称为“返回类型”)
-
compound-statement(在本主题的后面称为“lambda 体”)
以下各节对该语法进行了更详细的说明。
Capture 子句
& 前缀的引用和变量访问值由访问。
[ ] 指示 lambda 表达式的主体不访问封闭范围中的变量。
factor,那么以下 capture 子句等效:
[&total, factor] {factor, &total] [&, factor] [factor, &] [=, &total] [&total, =]
capture-default。
下面的代码段阐释了一些示例。
struct S { void f(int i); }; void S::f(int i) { [&, i]{}; // OK [&, &i]{}; // ERROR: i preceded by & when & is the default [=, this]{}; // ERROR: this when = is the default [i, i]{}; // ERROR: i repeated }
省略号 capture 后跟是 pack 扩展,以下面的示例:variadic 模板
template<class... Args> void f(Args... args) { auto x = [args...] { return g(args...); }; x(); }
Lambda 表达式的示例。
在使用子句获得时,应记住这些,理解和压力,尤其当使用具有多线程时的 lambda:
-
引用获取可用于修改变量之外,获取值,而无法用于修改变量之外 (变量允许复制修改,从原始的)。
-
而值获取不会反映更新给变量,则获取引用会反映更新到变量中。
-
而值获取没有生存期依赖关系,这些依赖关系的引用,获取引入生存期依赖关系,这些依赖关系。
许多这些点在这和相关文章中的代码示例所示。
参数列表
lambda declarator) lambda 表达式中为选项并类似于函数的参数列表。
Lambda 表达式的示例中的“高阶 Lambda 表达式”。
mutable。
可变规范
mutable 关键字的用法。
异常规范
C4297,如以下示例所示:
// throw_lambda_expression.cpp // compile with: /W4 /EHsc int main() // C4297 expected { []() throw() { throw 5; }(); }
返回类型
->,在返回类型。
考虑阐释此原则下面的示例代码段。
auto x1 = [](int i){ return i; }; // OK: return type is int auto x2 = []{ return{ 1, 2 }; }; // ERROR: return type is void, deducing // return type from braced-init-list not valid
Lambda 表达式的示例中的“高阶 Lambda 表达式”。
Lambda 体
普通函数和 lambda 表达式的主体均可访问以下变量类型:
-
参数
-
本地声明变量
-
this 内捕获)
-
具有静态存储持续时间的任何变量(例如,全局变量)
lambda 表达式的主体使用默认捕获模式来访问隐式捕获的变量。
m 的 lambda 表达式:
// captures_lambda_expression.cpp // compile with: /W4 /EHsc #include <iostream> using namespace std; int main() { int m = 0; int n = 0; [&, n] (int a) mutable { m = ++n + a; }(4); cout << m << endl << n << endl; }
本示例将以下内容输出到控制台:
5 0
n 是在 lambda 中修改。
lambda 表达式将修改静态变量以生成下一个元素的值。
void fillVector(vector<int>& v) { // A local static variable. static int nextValue = 1; // The lambda expression that appears in the following call to // the generate function modifies and uses the local static // variable nextValue. generate(v.begin(), v.end(), [] { return nextValue++; }); //WARNING: this is not thread-safe and is shown for illustration only }
生成。
1,在 lambda 后执行。
// compile with: /W4 /EHsc #include <algorithm> #include <iostream> #include <vector> #include <string> using namespace std; template <typename C> void print(const string& s, const C& c) { cout << s; for (const auto& e : c) { cout << e << " "; } cout << endl; } void fillVector(vector<int>& v) { // A local static variable. static int nextValue = 1; // The lambda expression that appears in the following call to // the generate function modifies and uses the local static // variable nextValue. generate(v.begin(), v.end(), [] { return nextValue++; }); //WARNING: this is not thread-safe and is shown for illustration only } int main() { // The number of elements in the vector. const int elementCount = 9; // Create a vector object with each element set to 1. vector<int> v(elementCount, 1); // These variables hold the previous two elements of the vector. int x = 1; int y = 1; // Sets each element in the vector to the sum of the // previous two elements. generate_n(v.begin() + 2, elementCount - 2, [=]() mutable throw() -> int { // lambda is the 3rd parameter // Generate current value. int n = x + y; // Update previous two values. x = y; y = n; return n; }); print("vector v after call to generate_n() with lambda: ", v); // Print the local variables x and y. // The values of x and y hold their initial values because // they are captured by value. cout << "x: " << x << " y: " << y << endl; // Fill the vector with a sequence of numbers fillVector(v); print("vector v after 1st call to fillVector(): ", v); // Fill the vector with the next sequence of numbers fillVector(v); print("vector v after 2nd call to fillVector(): ", v); }
vector v after call to generate_n() with lambda: 1 1 2 3 5 8 13 21 34 x: 1 y: 1 vector v after 1st call to fillVector(): 1 2 3 4 5 6 7 8 9 vector v after 2nd call to fillVector(): 10 11 12 13 14 15 16 17 18