C++ lambda表达式

下面将阐述lambda表达式的语法,内容主要参考自 Lambda Expression Syntax

如图,lambda表达式由下面几个部分构成:


  1. lambda-introducer (捕获字段)
  2. lambda-parameter-declaration-list (变量列表)
  3. mutable-specification (捕获的变量可否修改)
  4. exception-specification (异常设定)
  5. lambda-return-type-clause (返回类型)
  6. compound-statement (函数体)

外部变量的捕获规则

默认情况下,即捕获字段为 [] 时,lambda表达式是不能访问任何外部变量的,即表达式的函数体内无法访问当前作用域下的变量。

如果要设定表达式能够访问外部变量,可以在 [] 内写入 & 或者 = 加上变量名,其中 & 表示按引用访问,= 表示按值访问,变量之间用逗号分隔,比如 [=factor, &total] 表示按值访问变量 factor,而按引用访问 total。

不加变量名时表示设置默认捕获字段,外部变量将按照默认字段获取,后面在书写变量名时不加符号表示按默认字段设置,比如下面三条字段都是同一含义:

<span class="pun" style="color: rgb(102, 102, 0);">[&</span><span class="pln" style="color: rgb(0, 0, 0);">total</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> factor</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">[&,</span><span class="pln" style="color: rgb(0, 0, 0);"> factor</span><span class="pun" style="color: rgb(102, 102, 0);">]</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">[=,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">&</span><span class="pln" style="color: rgb(0, 0, 0);">total</span><span class="pun" style="color: rgb(102, 102, 0);">]</span>

参数列表

lambda表达式的参数列表基本和函数的一致,不过有如下限制:

  1. 参数列表不能有默认参数
  2. 不能是可变参数列表
  3. 所有的参数必须有个变量名

如果你不提供 mutable-specification, exception-specification, 以及 lambda-return-type-clause,参数列表是也可以省略的。如下面的表达式:

<span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> main</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">4</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">5</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> z </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[=]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">}();</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span>

能否修改捕获的变量

如果在参数列表后加上了 mutable,则表示表达式可以修改按值捕获的外部变量的拷贝。

异常设置

和函数一样,可以用 throw 来限定表达式能够抛出哪些异常。

返回类型

如果设置返回类型,你需要在类型名前面加上 ->。如果你只有一个返回语句的话,返回类型可以省略,编译器将会为你做出判断。

函数体

lambda表达式的函数体和普通函数大致相同。


下面是lambda表达式的几个完整例子:

<span class="com" style="color: rgb(136, 0, 0);">#include</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);"><algorithm></span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">#include</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);"><iostream></span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="com" style="color: rgb(136, 0, 0);">#include</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);"><vector></span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">using</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">namespace</span><span class="pln" style="color: rgb(0, 0, 0);"> std</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="com" style="color: rgb(136, 0, 0);">// The number of elements in the vector.</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="kwd" style="color: rgb(0, 0, 136);">const</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> elementCount </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">9</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> main</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> 
</span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">// Create a vector object with each element set to 1.</span><span class="pln" style="color: rgb(0, 0, 0);">
   vector</span><span class="str" style="color: rgb(0, 136, 0);"><int></span><span class="pln" style="color: rgb(0, 0, 0);"> v</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">elementCount</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">);</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">// These variables hold the previous two elements of the vector.</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">// Assign each element in the vector to the sum of the </span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">// previous two elements.</span><span class="pln" style="color: rgb(0, 0, 0);">
   generate_n</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">v</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="kwd" style="color: rgb(0, 0, 136);">begin</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> elementCount </span><span class="pun" style="color: rgb(102, 102, 0);">-</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="lit" style="color: rgb(0, 102, 102);">2</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[=]()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">mutable</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">throw</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">-></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
      
      </span><span class="com" style="color: rgb(136, 0, 0);">// Generate current value.</span><span class="pln" style="color: rgb(0, 0, 0);">
      </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> n </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="com" style="color: rgb(136, 0, 0);">// Update previous two values.</span><span class="pln" style="color: rgb(0, 0, 0);">
      x </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
      y </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> n</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

      </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> n</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">// Print the contents of the vector.</span><span class="pln" style="color: rgb(0, 0, 0);">
   for_each</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="pln" style="color: rgb(0, 0, 0);">v</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="kwd" style="color: rgb(0, 0, 136);">begin</span><span class="pun" style="color: rgb(102, 102, 0);">(),</span><span class="pln" style="color: rgb(0, 0, 0);"> v</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="kwd" style="color: rgb(0, 0, 136);">end</span><span class="pun" style="color: rgb(102, 102, 0);">(),</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[](</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> n</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> cout </span><span class="pun" style="color: rgb(102, 102, 0);"><<</span><span class="pln" style="color: rgb(0, 0, 0);"> n </span><span class="pun" style="color: rgb(102, 102, 0);"><<</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">" "</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">});</span><span class="pln" style="color: rgb(0, 0, 0);">
   cout </span><span class="pun" style="color: rgb(102, 102, 0);"><<</span><span class="pln" style="color: rgb(0, 0, 0);"> endl</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">

   </span><span class="com" style="color: rgb(136, 0, 0);">// Print the local variables x and y.</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">// The values of x and y hold their initial values because </span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">// they are captured by value.</span><span class="pln" style="color: rgb(0, 0, 0);">
   cout </span><span class="pun" style="color: rgb(102, 102, 0);"><<</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);"><<</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);">" "</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);"><<</span><span class="pln" style="color: rgb(0, 0, 0);"> y </span><span class="pun" style="color: rgb(102, 102, 0);"><<</span><span class="pln" style="color: rgb(0, 0, 0);"> endl</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span>
<span class="com" style="color: rgb(136, 0, 0);">#include</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="str" style="color: rgb(0, 136, 0);"><functional></span><span class="pln" style="color: rgb(0, 0, 0);">

</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> main</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="com" style="color: rgb(136, 0, 0);">// Assign the lambda expression that adds two numbers to an auto variable.</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">auto</span><span class="pln" style="color: rgb(0, 0, 0);"> f1 </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);"> 

   </span><span class="com" style="color: rgb(136, 0, 0);">// Assign the same lambda expression to a function object.</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">using</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">namespace</span><span class="pln" style="color: rgb(0, 0, 0);"> std</span><span class="pun" style="color: rgb(102, 102, 0);">::</span><span class="pln" style="color: rgb(0, 0, 0);">tr1</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);">
   </span><span class="kwd" style="color: rgb(0, 0, 136);">function</span><span class="pun" style="color: rgb(102, 102, 0);"><</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pun" style="color: rgb(102, 102, 0);">)></span><span class="pln" style="color: rgb(0, 0, 0);"> f2 </span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">[]</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> x</span><span class="pun" style="color: rgb(102, 102, 0);">,</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">int</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">)</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">{</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="kwd" style="color: rgb(0, 0, 136);">return</span><span class="pln" style="color: rgb(0, 0, 0);"> x </span><span class="pun" style="color: rgb(102, 102, 0);">+</span><span class="pln" style="color: rgb(0, 0, 0);"> y</span><span class="pun" style="color: rgb(102, 102, 0);">;</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">};</span><span class="pln" style="color: rgb(0, 0, 0);">
</span><span class="pun" style="color: rgb(102, 102, 0);">}</span><span class="pln" style="color: rgb(0, 0, 0);">
</span>

更多例子请参阅 Examples of Lambda Expressions,本文的数个例子也多来源于此。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值