lambada表达式



  1. lambda表达式

//C++ 11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。Lambda的语法形式如下:

//[函数对象参数](操作符重载函数参数)mutable或exception声明->返回值类型{函数体
}

 

//可以看到,Lambda主要分为五个部分:

//[函数对象参数]、(操作符重载函数参数)、mutable或exception声明、->返回值类型、{函数体
}。下面分别进行介绍。

//一、[函数对象参数],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。

//函数对象参数只能使用那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量(包括Lambda所在类的this)。函数对象参数有以下形式:

//1、空。没有使用任何函数对象参数。

//2、 =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。

//3、&。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。

//4、this。函数体内可以使用Lambda所在类中的成员变量。

//5、a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。

//6、&a。将a按引用进行传递。

//7、a, &b。将a按值进行传递,b按引用进行传递。

//8、 =,&a,&b。除a和b按引用进行传递外,其他参数都按值进行传递。

//9、&, a, b。除a和b按值进行传递外,其他参数都按引用进行传递。

//二、(操作符重载函数参数),标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,
b))和按引用(如:(&a, &b))两种方式进行传递。

//三、mutable或exception声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。

//exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)。

//四、->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

//五、{函数体
},标识函数的实现,这部分不能省略,但函数体可以为空。

案例1:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

 

//lambda表达式简单案例

voidmain()

{

//[函数对象参数]、(操作符重载函数参数)、mutable或exception声明、->返回值类型、{函数体
}

      autofun1
= [](){cout <<"hellochina"<<endl;
};

   fun1();

 

   autofun2
= [](inta,intb){returna
+b; };

   cout
<<fun2(10, 9) <<endl;

 

   std::cin.get();

}

运行结果:

案例2:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

 

voidmain()

{

   vector<int> myv;

   myv.push_back(1);

   myv.push_back(2);

   myv.push_back(11);

   autofun1
= [](intv){ cout
<<v <<endl;
};

   //通过这种方式操作myv中的值

   for_each(myv.begin(),myv.end(),fun1);

 

   cout
<<"----------------" <<endl;

 

   //直接写在内部,下面的v表示传递进lambda表达式的参数

   for_each(myv.begin(),myv.end(),[](intv)

   {

      cout
<<v <<endl;

   });

 

   std::cin.get();

}

运行结果:

案例3:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

 

voidmain()

{

   vector<int> myv;

   myv.push_back(1);

   myv.push_back(2);

   myv.push_back(11);

 

   inta
= 10;

   // =知道a的存在,可以引用,只能读,不可以写,引用当前块语句内部的局部变量

   autofun1
= [=](intv){v
+=a; cout
<<v <<endl; };

 

   for_each(myv.begin(),myv.end(),fun1);

   //此时a没有被修改

   cout
<<a <<endl;

   std::cin.get();

}

运行结果:

案例4:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

 

voidmain()

{

   vector<int> myv;

   myv.push_back(1);

   myv.push_back(2);

   myv.push_back(11);

 

   inta
= 10;

   //引用变量a,相当于直接操作a

   autofun1
= [&a](intv){a
= 3; v +=a; cout
<<v <<endl; };

 

   for_each(myv.begin(),myv.end(),fun1);

   //此时a发生变化

   cout
<<a <<endl;

   std::cin.get();

}

运行结果:

案例5:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

 

voidmain()

{

   [](){cout
<<"hellochina"; };//是一个函数指针

   [](){cout
<<"hellochina";}();//如果没有定义名称,如果想调用lambda表达式,可以直接在lambda表达式的最后面加上()

 

   cin.get();

}

运行结果:

案例6:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

 

classtest

{

public:

   vector<int> myv;

   intnum;

public:

   voidadd()

   {

       num
= 12;

       myv.push_back(10);

       myv.push_back(11);

 

       //[]引用this

       int x
= 3;

       autofun1
= [this,x](intv){cout
<<v+x+this->num
<< endl; };

       //=按照副本引用this,还有当前块语句局部变量,不可以赋值,但是可以读取

       //&按照引用的方式操作局部变量,this,可以赋值,可以读取

       //副本引用a,[=]  [a]

       //引用a
[&] [&a]

 

       autofun2
= [&](intv){cout
<<v +x
+this->num
<< endl;x
= 3; };

       for_each(this->myv.begin(),this->myv.end(),fun1);

       cout
<<"-----------------" <<endl;

       for_each(this->myv.begin(),this->myv.end(),fun2);

   }

};

 

voidmain()

{

   testt;

   t.add();

 

   cin.get();

}

运行结果:

案:7:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

//返回值案例

voidmain()

{

   //double是返回值类型

   autofun1
= []()->double{cout
<< "hello china" <<endl;return
1; };

   fun1();

 

   //通过decltype(a/b)的方式获得类型

   autofun2
= [](inta,doubleb)->decltype(a
/ b){cout
<< "hello china" <<endl;returna
/b; };

   fun2(1,
2.3);

 

   std::cin.get();

}

运行结果:

案例8:

#include<functional>

#include<iostream>

#include<vector>

#include<algorithm>

 

usingnamespacestd;

 

void main()

{

   inta
= 10;

   //mutable使可以改副本了。如果下面的去掉将会报错

   autofun1
= [a](intv)mutable->double{v
+= a; cout
<<v <<endl;a
= 3;return 3; };

   cout
<<a <<endl;

 

   std::cin.get();

   //运行结果还是10

}

Lambada表达式补充


{

        auto
func = []{return 1; };

        int
i = func();

        CCLog("i = %d",
i);

    }

    //最简单的lambada表达式是只要一个中括号和一个大括号

    //[]捕获列表

    //{}函数体

    //1.捕获列表,可以放变量名,这里可以用来传递函数体内定义的变量

    {

        int
v = 100;

        auto
func = [v]{return
v; };

        int
x = func();

    }

 

    //2.捕获列表,可以捕获多个变量

    {

        int
p = 100, q = 200;

        auto
func = [p, q]{return
p + q; };

        int
s = func();

    }

 

    // 3.捕获列表,有引用和传值两种方式,传值不可以改变,引用可以改变,并且改变外部的变量值

    {

        int
p = 100, q = 200;

        auto
func = [p, &q]{q++; 
return p +
q; };

        int
s = func();

    }

 

    //4.捕获列表,可以定义mutable类型的lambada,能改变传值的捕获参数,

    //但是不能改变外部的变量值

    {

        int
p = 100, q = 200;

        auto
func = [p, q]()mutable{p++;
q++; return
p + q; };

        int
s = func();

        CCLog("p = %d,q = %d,s = %d",
p, q,
s);

    }

 

    //5.捕获列表,可以用=或者&捕获所有变量,=指传值,&表示引用

    {

        int
p = 100, q = 200;

        //用&的时候,所有的都可以调用了,[&,p]:表示除了p不能被使用,其它的都可以被使用

        auto
func = [&]{

            return
p + q;

        };

    }

 

    //稍微复杂点的lambda表达式

    {

        auto
add = [](int v1,
int v2){return
v1 + v2; };

        auto
a = add(1 , 2);

    }

 

    //小括号中的是参数列表,参数列表和捕获列表区别在于,参数列表的参数由调用方决定,

    //捕获列表由定义方决定,所以更加灵活

 

    //更加复杂的lambada表达是,有返回值,返回值一般都省略

    {

        //->int表示返回值是int类型的

        auto
add = [](int v1,
int v2)->int{return
v1 + v2; };

    }

 

    //总结:auto func = [](){}

    {

        auto
func = [](){};

    }

 

 

时间: 2024-08-31 21:31:46

lambada表达式的相关文章

2.cocos2dx 3.2中语法的不同之处,lambada表达式的使用和function和bind函数的使用

1        打开建好的T32  Cocos2dx-3.2的一个项目 2        设置Cocos显示窗口的位置是在AppDelegate.cpp中: 3  设置自适应窗口大小的代码是在上面的代码后面紧接着就添加: glview->setDesignResolutionSize(480,320, ResolutionPolicy::EXACT_FIT);   3        cocos2d-x-3.2项目案例(3.2版本之后都去掉了CC前缀) 4        项目目录结构如下: 编写

C#中提供的VB不支持的新特性

在Beta 2中,.NET中的两种旗舰语言--C#和Visual Basic各自的功能集合都已经确定.以前我们曾经介绍过只在VB中出现的特性,例如可变匿名类型和XML常量等.而今天本文则要介绍一些只在C#中出现的特性. 第一个特性是用于创建数据类的一个语法上的便捷之处.借助于自动属性(Automatic Properties)语法,C#开发者无需书写任何重复的代码即可容易地创建属性. public int X { get; private set; } 上面这句代码创建了一个名为X的属性,该属性

C#3.0笔记(一)预备知识之Delegate

在学习C#3.0之前还是先来回顾下委托.事件,因为这样能更加有助于理解 C#3.0里面的一些新的特性,如Lambada表达式等. 背景 在C语言 中我们可以用函数指针来创建回调函数,但是在C里面回调函数存在一些安全问 题.因为它只是在内存地址中记录了下来,并没有像方法的参数类型.参数个数 .返回值等其他安全信息.而在.Net FrameWork中,回调仍然是可以的,.net framework中提供了更为高级的更为安全的面向对象的delegate来实现. 定义委托 在委托中主要包含了三个重要的信

[Python] 专题五.列表基础知识 二维list排序、获取下标和处理txt文本实例

        通常测试人员或公司实习人员需要处理一些txt文本内容,而此时使用Python是比较方便的语言.它不光在爬取网上资料上方便,还在NLP自然语言处理方面拥有独到的优势.这篇文章主要简单的介绍使用Python处理txt汉字文字.二维列表排序和获取list下标.希望文章对你有所帮助或提供一些见解~ 一. list二维数组排序         功能:已经通过Python从维基百科中获取了国家的国土面积和排名信息,此时需要获取国土面积并进行排序判断世界排名是否正确.         列表基础

艾伟:C#3.0笔记(一)预备知识之Delegate

在学习C#3.0之前还是先来回顾下委托.事件,因为这样能更加有助于理解C#3.0里面的一些新的特性,如Lambada表达式等. 背景 在C语言中我们可以用函数指针来创建回调函数,但是在C里面回调函数存在一些安全问题.因为它只是在内存地址中记录了下来,并没有像方法的参数类型.参数个数.返回值等其他安全信息.而在.Net FrameWork中,回调仍然是可以的,.net framework中提供了更为高级的更为安全的面向对象的delegate来实现. 定义委托 在委托中主要包含了三个重要的信息: 1

PostgreSQL 索引虚拟列 - 表达式索引 - JOIN提速

标签 PostgreSQL , join , 表达式索引 , 虚拟列索引 , 静态数据 , immutable函数 背景 CASE: 使用虚拟索引,响应时间从2.3秒下降到0.3毫秒 业务系统在设计时,为了减少数据冗余,提升可读性,通常需要将不同的数据放到不同的表. 在查询时,通过多表JOIN来补齐需要查询或在过滤的内容. 比如这样的例子: 有两张表,分别有1千万和100万数据,当用户查询时,需要补齐那100万表中的某个字段进行过滤. create table a (id int, bid in

jsp-JSP中编写JS代码过程中,调用了一个JSP表达式,发现一个问题,麻烦各位大神解答

问题描述 JSP中编写JS代码过程中,调用了一个JSP表达式,发现一个问题,麻烦各位大神解答 背景: 楼主使用Myelipse新建了一个Web项目,在编写一个JSP文件的时候遇到一个问题,首先是使用了img,并且写了一个事件,代码如下: <imgclass="poke" src="poke/back.jpg" title="hit" id="play_id_3" onClick="change_pic()&qu

表达式-/ 100 + 3 * - 2 4 / 20 10

问题描述 / 100 + 3 * - 2 4 / 20 10 已知一个表达式的后缀形式是/ 100 + 3 * - 2 4 / 20 10求它的前缀形式? 解决方案 这就是前缀吧中缀是 100/(3+((2-4)*20/10))后缀 100 3 2 4 - 20 * 10 / + /

select-link能不能直接调用方法?还是只能写表达式?

问题描述 link能不能直接调用方法?还是只能写表达式? link能不能直接调用方法?还是只能写表达式? int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 }; var query = from x in array where Predicate select x; foreach (int item in query) Console.WriteLine(item); bool Predicate(int n) { if (n % 2 == 0) return t