C++ lamda表达式

lamda表达式是C++11中的新特征,说白了就是匿名函数。
    
    lambda表达式的具体形式如下:



 [capture](parameters)->return-type{body}



其中, capture是需要用到的外部变量, parameters是函数参数,return-type是返回的类型(可省略),body是函数体。

来个最简单的:

[](){};

 ”[]"表示不需要使用外部变量,”()"表示形参列表为空,"{}"表示空函数,什么都不干。

再举一个例子。
    在STL中有一个排序函数std::sort,如果现在我们要用它来按降序排列一个数组arr,则可自定义一个比较函数cmp,并把它传给sort函数,如下

 bool cmp(int a, int b) {

    return a > b;

  }

  std::sort(arr, arr + len, cmp);

  

  若果使用lamda表达式,则可改写成如下

std::sort(arr, arr + len, [](int a, int b) {

    return a > b;

  });


  

  "[]"表明没有用到外部变量,如果我们要用到外部变量,则要对"[]"进行修改,如下代码

  int n = 10;

  [](int a) {return a + n;}; // 报错,提示变量n不能在lamda体中调用,除非其在捕获列表中

  捕获列表是指"[]",因此我们在"[]"中加上n即可。如下

  int n = 10;

  [n](int a) {return a + n;}; // 正确

  "[n]"说明n是以传值的方式传到lamda体中,传值和传引用的差别请自行百度。捕获列表可按如下规则传入

  • [] 什么也没有捕获
  • [a, &b] 按值捕获a,按引用捕获b
  • [&] 按引用捕获任何用到的外部变量
  • [=] 按值捕获任何用到的外部变量
  • [a, &] 按值捕获a, 其它的变量按引用捕获
  • [&b, =] 按引用捕获b,其它的变量按值捕获
  • [this] 按值捕获this指针

  注意: 假如我们想修改按值传进来的形参,将会发生错误,因为按值捕获的对象不能被修改,如下代码

   int n = 10;
    [n](int a) {
        n += a; // 报错,提示不允许修改n的值
        return n;
    };

  

  这时我们需要假如一个mutable,如下

    int n = 10;
    [n](int a)mutable {
        n += a; // 正确
        return n;
    };


  关于返回值类型,可由以下规则推导出来

  • 如果body仅包含单一的return语句,那么返回值类型是返回表达式的类型(在此隐式转换之后的类型:右值到左值、数组与指针、函数到指针)
  • 否则,返回类型是void

  譬如我们上面std::sort()的这个例子,lamda表达式是

[](int a, int b) {return a > b;};

  a > b 这个表达式返回的类型是bool,因此这个lamda表达式返回类型是bool。

  最后一个例子,我们可以把lamda表达式进行赋值,还是利用std::sort()这个例子。我们可以把cmp函数写成如下

std::function<bool(int, int)> cmp = [](int a, int b) {return a > b;};  //std::function包含在头文件functional中,具体用法请自行百度

  这样做的好处是可以多次利用lamda表达式。当然,我们可以指定其返回类型为auto,来让其自行判断。

auto cmp = [](int a, int b) {return a > b;};

  



  lamda表达式的简单介绍到此结束。文章若有错漏之处,请提出,多谢。

  

  参考:

    Lambda函数(C++11 起):http://zh.cppreference.com/w/cpp/language/lambda
    代码简洁之道:C++ 11 之auto+ for_each + lamda表达式:http://www.itnose.net/detail/6090413.html

  

时间: 2024-11-05 12:17:06

C++ lamda表达式的相关文章

JAVA8新特性——Lamda表达式

JAVA9都要出来了,JAVA8新特性都没搞清楚,是不是有点掉队哦~ Lamda表达式,读作λ表达式,它实质属于函数式编程的概念,要理解函数式编程的产生目的,就要先理解匿名内部类. 先来看看传统的匿名内部类调用方式: interface MyInterface{ void lMethod(); } public class Main { public static void test(MyInterface myInterface){ myInterface.lMethod(); } publi

[.net 面向对象程序设计进阶] (5) Lamda表达式(二) 表达式树快速入门

[.net 面向对象程序设计进阶] (6) Lamda表达式(二) 表达式树快速入门 本节导读: 认识表达式树(Expression Tree),学习使用Lambda创建表达式树,解析表达式树. 学习表达式在程序设计中的优点:比如构造动态查询.动态构造表达式树完成未知对象属性访问,比反射的性能高出很多.我们可以说表达式树才是Lambda的精髓,是我们必须要熟练掌握并灵活运用的. 1.关于表达式树(Expression Tree) 表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如

C#学习记录(七)LINQ语句及LAMDA表达式

LINQ LINQ是一种集成在计算机语言里的信息查询语句,可以让编写者以代码的方式操作数据库. 在C#中,LINQ语句有两种写法. 这是第一种写法 IEnumerable<Customer> result = from customer in customers where customer.FirstName == "Donna“ select customer; 由于这种写法比较容易和SQL语言混淆,所以我更倾向于使用另一种写法 IEnumerable<Customer&g

匿名方法与Lamda表达式

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 匿名方法与Lamda表达式 { class Program { static void Main(string[] args) { //任何可以使用委托的地方都可以使用匿名方法,匿名方法就是没有名字的方法. //a指向一个匿名方法 Action a

委托、泛型委托、多播委托 和 lamda表达式

委托基本概念:可以把一个方法作为一个参数传给另一个方法 声明:  方法前加 delegate  关键字 列子: using System; using System.Collections; using System.Collections.Generic; namespace Dome { class dom { static void Main(string[] args) { string[] sname = { "Abc", "dFg", "HjK

Lamda 表达式学习(2) ——lamda 变换

回顾λ-calculus语法: t ::=  terms: x  variable λx.t  abstraction t t  application λ-变换:保持λ-项含义的同时对其进行变换. 1. α-变换:改变被绑定变量的名称,所代表的含义仍是一样的. λx.t → λy.t(x:=y) (将表达式的body t中的所有x的自由出现替换称y) 两个lamda表达式如果可以通过α-变换(可能应用到子项)从一个变换到另外一个,则称他们是全等的. 2. β-规约:对application的变

java中lamda表达式的应用

lamda表达式主要是为了解决匿名内部类的繁琐过程 范例:简单的lamda表达式 此处使用匿名内部类 package com.java.demo; interface IMessage{ public void print();//抽象方法 } public class TestDemo{ public static void main(String args[]){ //使用给匿名内部类实现print()方法 fun(new IMessage(){ public void print(){ S

LINQ的左连接、右连接、内连接和Lamda表达式实现Left join

1.左连接: var LeftJoin = from t1 in l1join t2 in l2on t1.ID equals t2.ID into Joinedt12from t3 in Joinedt12.DefaultIfEmpty()select new                        {Name = t1.Name,Age=t2.Age                      };   2.右连接: var RightJoin = from t2 in l2join t

[.net 面向对象程序设计进阶] (5) Lamda表达式(一) 创建委托

[.net 面向对象程序设计进阶] (5) Lamda表达式(一)  创建委托 本节导读: 通过学习Lambda表达式,学会创建委托和表达式目录树,深入了解Lambda的特性,让你的代码变的更加清晰.简洁.高效. 读前必备: 本节学习前,需要掌握以下知识: A.泛型        (请参考[.net 面向对象编程基础]  (18) 泛型) B.Linq基础 (请参照[.net 面向对象编程基础] (19) LINQ基础) C.Linq使用  (请参照[.net 面向对象编程基础]  (20) L

什么是lamda表达式?

我们首先来看一下这一片代码: 1 class Solution { 2 public: 3 int singleNumber(int A[], int n) { 4 // Note: The Solution object is instantiated only once and is reused by each test case. 5 int retval = 0; 6 for_each(A, A+n, [&retval](int val){retval ^= val;}); 7 ret