Lambda 表达式语法

本主题介绍 lambda
表达式的语法。 它演示提供 lambda
表达式的结构元素的示例,这些元素与示例。

Lambda 表达式语法

lambda expression (items marked with the opt subscript are optional):‘
data-guid="7c06475b6c7e659231eab3f6a09da2c5">下面用于定义显示语法,ISO C++11 从标准,lambda 表达式 (项标记下标 选择 是可选的):

lambda-introducer lambda-declaratoroptcompound-statement‘
data-guid="da567d9b01ffc90b2f806d6102b02c8a"> lambda-introducer lambda-declarator 选择 compound-statement

进一步失败的组件这些语法如下:

lambda-introducer: 
        [lambda-captureopt]‘
data-guid="e4c05141edef0d183536397ad2313d5b"> [ lambda-capture 选择 ] 
lambda-capture:
        capture-default
        capture-list
        capture-default,capture-list‘
data-guid="ded357489ff523ebac123eeea9f8e5b9"> capture-default , capture-list 
capture-default:
        &
        =
capture-list:
        capture ...opt‘
data-guid="7fc7bb76894402a3f57acea82c41a6c9"> capture ... 选择 
        capture-list,capture ...opt‘
data-guid="907b62c7b64c05e8dc0e3f9538d728e4"> capture-list , capture
... opt 
capture:
        identifier
        &identifier‘
data-guid="7feb2bf421ffc991f9d142012cdc8a6e"> & identifier 
        this
lambda-declarator:
        (parameter-declaration-clause)mutableopt‘
data-guid="99306ee62067d0154f8608c670fd2325"> ( parameter-declaration-clause ) mutable 选择 
                exception-specificationoptattribute-specifier-seqopttrailing-return-typeopt‘
data-guid="c5b4a2734548c72609a9e160f562296d"> exception-specification 选择 attribute-specifier-seq 选择 trailing-return-type 选择

Visual Studio 支持 C++11 标准 Lambda
表达式语法及其所有 C++11 功能与除了 lambda,以下操作:

  • 要,任何其他类,不会自动生成的构造函数并将不根据标准要求将赋值运算符。 Rvalue References section of Support For C++11 Features (Modern C++).‘
    data-guid="1f15aa4e6b46f9f25fa58ab28a364497">有关 rvalue
    引用行为支持的更多信息,请参见 
    C++11 功能的支持(现代 C++)
    中的 Rvalue
    References 节。

  • attribute-specifier-seq is not yet supported.‘
    data-guid="105a6431ee4e5f929e7a14b7486a6ae8">可选的 attribute-specifier-seq 不支持。

Visual Studio 向 C++11 lambda
功能通过添加以下功能:

    • 无状态是 lambda omni
      转换的任意函数使用调用约定的函数的指针。

    • { return expression; } as long as all return statements have the same type. (This is now in the proposed C++14 Standard.)‘
      data-guid="c4be162dba4357621396c005aa9f91ab">比 {
      return expression; } 复杂的主体的 lambda 自动返回这样的类型,只要所有返回语句具有相同的类型。(这在
      C++14 标准现在建议的)。

Lambda
表达式的属性

下图将该语法映射到示例。

图中的标注如下所示:

  1. lambda-introducer (referred to as capture clause later in this topic)‘
    data-guid="230e892924e79481c72a4e79d3ef8021">lambda-introducer(在本主题的后面称为“capture 子句”)

  2. lambda declarator (referred to as parameter list later in this topic)‘
    data-guid="f7132131cadfe2fae3609f17053090bd">lambda
    declarator(在本主题的后面称为“参数列表”)

  3. mutable (referred to as mutable specification later in this topic)‘
    data-guid="5948943488e9ef1abebb45c43b50debf">mutable(在本主题的后面称为“可变规范”)

  4. exception-specification (referred to as exception specification later in this topic)‘
    data-guid="f1d1f05ee188f2edd9f9a14bff636d23">exception-specification(在本主题的后面称为“异常规范”)

  5. trailing-return-type (referred to as return type later in this topic)‘
    data-guid="f4000e6e2709000c8f72714c0ecc46ad">trailing-return-type(在本主题的后面称为“返回类型”)

  6. compound-statement (referred to as lambda body later in this topic)‘
    data-guid="281c9b34dbcf1da68852dab92d14c081">compound-statement(在本主题的后面称为“lambda 体”)

以下各节对该语法进行了更详细的说明。

Capture 子句

lambda
表达式是类、构造和函数调用运算符。 如同,在定义类时,决定需要发生的对象捕获变量不受值还是引用或者是否是必需的。 captured.‘
data-guid="6c33afef79a40306c474574370f5d5d3">如果 lambda
表达式需要访问局部变量和函数参数,它们需要 捕获。 lambda-introducer in the syntax) specifies whether the body of the lambda expression can access variables in the enclosing scope by value or by reference: Variables that have the ampersand (&) prefix are accessed by reference and variables that do not have the & prefix are accessed by value.‘
data-guid="c40c2b1e1b09d1b6c817849b8f6620a7">get 子句 (语法中的lambda-introducer ) 所指定 lambda
表达式的主体是可以访问在封闭范围内的变量通过值或通过引用:包含" &的变量 (&) 为前缀) 没有 & 前缀的引用和变量访问值由访问。

[ ], indicates that the body of the lambda expression accesses no variables in the enclosing scope.‘
data-guid="63675b2a3256576c874023b197bac1c0">空 capture 子句 [ ] 指示 lambda 表达式的主体不访问封闭范围中的变量。

捕获默认模式指定您未显式指定的获取变量是否捕获通过值或通过引用,如果使用它们。 capture-default in the syntax) by specifying & or = as the first element of the capture clause.‘
data-guid="06ca7cba6d4564676c3248770ee0e3f1">您可以通过将 & 或 = 指定为 capture 子句的第一个元素来指定默认捕获模式(语法中的 capture-default)。 & element specifies that the body of the lambda expression accesses all captured variables by reference unless you explicitly specify otherwise.‘
data-guid="e1b847322b78a606bba9d77c52fe04be">& 元素指定 lambda
表达式的主体通过引用访问所有捕获的变量,除非您显式地另行指定。 = element specifies that the body of the lambda expression accesses all captured variables by value unless you explicitly specify otherwise.‘
data-guid="ee082ebeb43766571328678d7d2f24fe">= 元素指定 lambda
表达式的主体通过值访问所有捕获的变量,除非您显式地另行指定。 total by reference and the external variable factor by value, then the following capture clauses are equivalent:‘
data-guid="5bad063af18403fe3f4e25e148c3651f">例如,如果 lambda
表达式的主体通过引用访问外部变量 total 并通过值访问外部变量 factor,那么以下 capture 子句等效:

[&total, factor]
{factor, &total]
[&, factor]
[factor, &]
[=, &total]
[&total, =]

capture-default is that all variables in the scope are captured whether they are used in the lambda or not.‘
data-guid="b08db9512b44b311fa2f9cc31c0b2a9e">有关使用 capture-default 的一种常见的误会位于范围内的任何变量捕获是否使用
lambda。 capture-default.‘
data-guid="cc904375d879668befe499b0b9a84de0">事实上并非如此 - 在 lambda
提到的那些变量捕获,则使用 capture-default。

capture-default&, no identifier in a capture of that lambda‘s capture clause can be preceded by &."
data-guid="09e4b214fc6c520b711efe30b93ca6ab">如果捕获子句包括 capture-default&,该 lambda 的 get 子句 capture 的 identifier 不能由 &。 capture-default (=), each capture of that capture clause must be in the form & identifier.‘
data-guid="1cb38aa3342faf3177ce98fff2e74c79">沿着同一行,因此,如果获取子句包括 capture-default (=),该子句获得每个 capture 必须以窗体 &
identifier。 this cannot appear more than once in a capture clause.‘
data-guid="cf4debaa20847e79b392630c6e1a44b3">标识符或 this 不能多次出现在子句获得。 下面的代码段阐释了一些示例。


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
表达式用于类方法的主体中。 this pointer to the capture clause to provide access to the methods and data members of the enclosing class.‘
data-guid="8d00bf9c4599b0608293c600ef7b1a2c">将 this 指针传递到 capture
子句以提供对封闭类的方法和数据成员的访问权限。 Examples of Lambda Expressions.‘
data-guid="c858eb99637a672271f25aae1cec6179">有关示例演示如何使用类用方法的 lambda
表达式,请参见示例:使用将方法的 Lambda 表达式。主题 Lambda
表达式的示例

在使用子句获得时,应记住这些,理解和压力,尤其当使用具有多线程时的
lambda:

  • 引用获取可用于修改变量之外,获取值,而无法用于修改变量之外
    (变量允许复制修改,从原始的)。

  • 而值获取不会反映更新给变量,则获取引用会反映更新到变量中。

  • 而值获取没有生存期依赖关系,这些依赖关系的引用,获取引入生存期依赖关系,这些依赖关系。

许多这些点在这和相关文章中的代码示例所示。

参数列表

lambda declarator) for a lambda expression is optional and resembles the parameter list for a function.‘
data-guid="63f201d4283b35f483995264d43f8d72">参数列表 (lambda declarator) lambda
表达式中为选项并类似于函数的参数列表。

lambda 表达式可以将另一个 lambda
表达式作为其参数。 Examples of Lambda Expressions.‘
data-guid="5de864549207e726053ee89acb16218d">有关详细信息,请参阅主题 Lambda
表达式的示例
中的“高阶 Lambda 表达式”。

lambda
表达式的参数列表可以是可选的。 lambda-declarator: does not contain exception-specification, trailing-return-type, or mutable.‘
data-guid="bb965b1339c1e3ea4048508edca1123a">可以省略空括号,如果不传递参数到 lambda
表达式,并且 lambda-declarator: 不包含 exception-specification、trailing-return-type、mutable。

可变规范

mutable cancels this out."
data-guid="f4865f573c3a55ba26eaf372873dd943">通常的 lambda 函数调用运算符为 Const
按值,但是,mutable 可以取消此操作。 它不导致变量的数据成员。 可变规范使用 lambda
表达式的主体修改由捕获值的变量。 mutable keyword.‘
data-guid="081cbf492611ee14dd8055b696cf8c29">某些示例本文后面演示了 mutable 关键字的用法。

异常规范

throw() exception specification to indicate that the lambda expression does not throw any exceptions.‘
data-guid="864feb25d624512223eac67ca5e65a0d">您可以使用 throw() 异常规范来指示
lambda 表达式不会引发任何异常。 C4297 if a lambda expression declares the throw() exception specification and the lambda body throws an exception, as shown in the following example:‘
data-guid="51492dd90d3455655471188842c736ef">与正则函数一样,如果 lambda
表达式声明 throw() 异常规范且 lambda
体引发异常,Visual C++ 编译器将生成警告 C4297,如以下示例所示:

// throw_lambda_expression.cpp
// compile with: /W4 /EHsc
int main() // C4297 expected
{
[]() throw() { throw 5; }();
}

返回类型

auto keyword unless a trailing-return-type is specified.‘
data-guid="c38d414de342a6f2033ff784ef760918">lambda
表达式的返回类型自动推断,并且,这发生,而无需添加关键字,除非指定 trailing-return-type。auto trailing-return-type resembles the return type part of an ordinary method or function.‘
data-guid="c2fa50eaa88f4b294a0827a5d39305b0">trailing-return-type 类似于普通方法或函数返回类型的部件。 -&gt; before the return type.‘
data-guid="f32cc4800f78ae0b4a707e2f4b348df9">但是,遵循返回类型参数列表,您必须包括尾部的返回类型关键字 ->,在返回类型。

如果 lambda 体包含单个返回语句或 lambda
表达式不返回值,则可以省略 lambda 表达式的返回类型部分。 如果 lambda
体包含单个返回语句,编译器将从返回表达式的类型推导返回类型。 void.‘
data-guid="dbcad1a80c2671c1e63e83dbb889d62b">否则,编译器会将返回类型推导为 void(可能需要显示指明返回类型)。 考虑阐释此原则下面的示例代码段。

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
表达式作为其返回值。 Examples of Lambda Expressions.‘
data-guid="5de864549207e726053ee89acb16218d">有关详细信息,请参阅主题 Lambda
表达式的示例
中的“高阶 Lambda 表达式”。

Lambda 体

compound-statement) part of a lambda expression can contain anything that the body of an ordinary method or function can contain.‘
data-guid="f6f7711b58566f4e0ba3338648808408">lambda 表达式主体的 lambda (compound-statement)
中可以包含一般的方法或函数主体所能包含的所有内容。 普通函数和 lambda
表达式的主体均可访问以下变量类型:

  • 参数

  • 本地声明变量

  • this is captured)‘
    data-guid="061c2060e88df49524cd1ca88ab3cd19">类数据成员 (在声明类和 this 内捕获)

  • 具有静态存储持续时间的任何变量(例如,全局变量)

此外,lambda
表达式可以访问它从封闭范围中捕获的变量。 explicitly captured if it appears in the capture clause of the lambda expression.‘
data-guid="4b80d2b6a52c7399c0814480cbe56ad4">如果某个变量显示在 lambda 表达式的 capture
子句中,则该变量是显式捕获的。 implicitly captured.‘
data-guid="452895ab9d3dc569058e37c3da341035">否则,该变量是隐式捕获的。 lambda
表达式的主体使用默认捕获模式来访问隐式捕获的变量。

n by value and implicitly captures the variable m by reference:‘
data-guid="2fa2baef7118434466b3bf796a5f9c70">以下示例包含通过值显式捕获变量 n 并通过引用隐式捕获变量 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 is captured by value, its value remains 0 after the call to the lambda expression.‘
data-guid="cd5a3531d8a41f6e44e7be185f221c83">由于变量 n 是通过值捕获的,因此在调用 lambda 表达式后,变量的值仍保持 0 不变。 mutable specification allows n to be modified within the lambda.‘
data-guid="2b5ab9c1f809320dd5702b305da46788">指定 mutable 允许 n 是在 lambda 中修改。

尽管 lambda
表达式只能捕获具有自动存储持续时间的变量,但您可以在 lambda 表达式的主体中使用具有静态存储持续时间的变量。 generate function and a lambda expression to assign a value to each element in a vector object."
data-guid="13f4c7652ade19bdf74c491934871db5">以下示例使用 generate 函数和
lambda 表达式为 vector 对象中的每个元素赋值。 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
}

generate function, see generate. ‘
data-guid="d7921455d70fff4b583ab6a110d1cabf">有关 generate 函数的详细信息,请参阅 生成

generate_n."
data-guid="f37655cfd2334cb5111d116e08df40b1">下面的代码示例使用从前面的函数,并将该表达式的 lambda
表达式的示例与 STL generate_n的算法。 vector object to the sum of the previous two elements."
data-guid="f843731a1766316f97795516fbaef583">该 lambda
表达式分配的 vector 对象的元素。前两个元素的和的。 mutable keyword is used so that the body of the lambda expression can modify its copies of the external variables x and y, which the lambda expression captures by value.‘
data-guid="08d948f43c776a52ea7576cf6e11a107">改用 mutable 关键字,这样 lambda 表达式体才能改变其外部变量 x 和 y的复制,lambda
表达式按值捕获。 x and y by value, their values remain 1 after the lambda executes.‘
data-guid="79c37a26742c33aa9f3aff17d10e8cc7">由于 lambda 表达式按值捕获原始变量 x 和 y,它们的值保持为 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



Lambda 表达式语法

时间: 2024-10-24 14:42:04

Lambda 表达式语法的相关文章

Java8初体验(1):lambda表达式语法

原文出处: 一冰_天锦 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解偏差的地方,希望大家帮忙指出,我会持续修改和优化.本文是该系列的第一篇,主要介绍Java8对屌丝码农最有吸引力的一个特性—lambda表达式. java8的安装 工欲善其器必先利其器,首先安装JDK8.过程省略,大家应该都可以自己搞定.但是有一点这里强调一下(Windows系统):目前我们工作的版本一般是java 6或者java 7,所以很多人安

lambda表达式语法与函数式编程接口

java8中lambda表达式的两种语法 1.(parameters) ->expression   单表达式 2.(parameters) ->{statements;}  语句 语法解释 (parameters),lambda表达式的参数列表,其定义方法为JAVA普通的方法相同,例如(Object a, Object b). -> 箭头,是参数列表与lambda表达式主题部分的分隔符号. ------------------------------------------------

一课掌握Lambda表达式语法及作用简单入门1??

通过三个方面讲解Lambda表达式 1  什么是Lambda表达式 2  Lambda表达式基础知识 3  Lambda表达式高级扩展 分为三个层次去介绍一下Lambda表达式 重构结束后,我们针对性能问题进行讲解, 1 什么是Lambda表达式 2 Model Code As Data 3 功能接口设计及优化 4 为什么要使用Lambda表达式 Lambda表达式,也可以成为箭头函数,匿名函数,闭包 Lambda表达式体现的是轻量级函数方式编程思想 JDK8新特性 -> 左边操作参数,右侧是操

java8 lambda表达式-语法

什么事lambda表达式,在百科的解释是 "Lambda 表达式"(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数.Lambda表达式可以表示闭包(注意和数学传统意义上的不同). 在java中我理解是匿名类,或者参数表达式(带有参数的可执行的代码块). (Type1 param1, Type2 param2, ..., TypeN

java8之lambda表达式(lambda表达式语法)

到目前为止,在Java中向其他代码传递一段代码并不是很容易.你不可能将代码块到处传递.由于java是一个面向对象的语言,因此你不得不构建一个属于某个类的对象,由它的某个方法来包含所需的代码. lambda表达式帮我们解决了这个问题,可以直接传递代码块!Java中lambda表达式的格式:参数,箭头(->),以及一个表达式.示例: (String first,String second) -> Integer.compare(first.length(), second.length()) 如果

Java8 Lambda表达式深入学习(4) -- Java8实现方式

前几篇文章讨论了函数式接口和Lambda表达式语法.invokedynamic指令,以及Groovy2如何利用indy指令.本篇文章在前面几篇的基础之上,简要介绍Java8底层是如何实现Lambda表达式的. 示例代码 本文将以下面的代码为例展开讨论: import java.util.Arrays; import java.util.List; public class LambdaImplTest { public static void main(String[] args) { m1(A

Scheme中lambda表达式与函数指针小例

SICP/Chapter2/Exercise-2.4 Lambda表达式语法 (lambda kw-formals body) 题目描述 用过程性表示方式重写序对的cons.car.cdr Scheme代码 (define (cons-24 x y) (lambda (m) (m x y))) (define (car-24 z) (z (lambda (p q) p))) 这段代码只有4行,但是逻辑关系并不好理解. 原因在于函数式语言的自顶向下实现方式不符合一般的逻辑习惯. lambda以类似

Android Stutio中使用java8的Lambda表达式

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51532028 本文出自:[openXu的博客] 目录: 为什么要使用Lambda表达式 让Android Stutio支持Lambda 函数式接口Functional interfaces Lambda表达式的目标类型以及匹配 Lambda表达式语法 1 基础语法和语法简化 2 Lambda表达式的词法作用域 3 变量捕获 ??Java 8的一个大亮点是引入Lambda表达式,使用它设计的

C++11中新特性之:lambda 表达式

首先摆出Lambda表达式语法 lambda-expression: lambda-introducer lambda-declaratoropt compound-statementlambda-introducer: [ lambda-captureopt ] lambda-capture: capture-default capture-list capture-default , capture-listcapture-default: & =capture-list: capture