精华内容
下载资源
问答
  • c++ lambda表达式

    2017-08-31 16:16:25
    c++ lambda表达式

    简单来说,Lambda函数也就是一个函数,它的语法定义如下:

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

    分别为:捕获列表,参数,关键字修饰(const mutable等),返回类型,函数体

    1.[capture]:捕捉列表。捕捉列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数。捕捉列表能够捕捉上下文中的变量以供Lambda函数使用;

    2.(parameters):参数列表。与普通函数的参数列表一致。

    3.mutable:mutable修饰符。默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。

    4.->return-type:返回类型。用追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导;

    5.{statement}:函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

    与普通函数最大的区别是,除了可以使用参数以外,Lambda函数还可以通过捕获列表访问一些上下文中的数据。具体地,捕捉列表描述了上下文中哪些数据可以被Lambda使用,以及使用方式(以值传递的方式或引用传递的方式)。语法上,在“[]”包括起来的是捕捉列表,捕捉列表由多个捕捉项组成,并以逗号分隔。


    其调用方式与函数类似,实例如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <fstream>
    #include <iostream>
    using namespace std;




    int main()
    {
    /*
    [=] 采用值捕获方式捕获所有父作用域的变量(包括this指针)
    [var]采用值捕获方式捕获父作用域的变量var    
    [&]采用引用捕获方式捕获父作用域所用变量
    [&var]采用引用捕获方式捕获父作用域的变量var
    捕获列表里可以用,号隔开捕获多个变量。
    注意:采用值捕获的方式捕获的变量,看lambda函数有没被mutable修饰,有则捕获的变量可以作左值,否则捕获的变量为在lambda函数里为常量;采用引用捕获方式捕获的变量,在lambda函数里是一个变量。


    */
    int a =10;
    //auto func = [=]()->int{return a=0;};错误,[=]采用值捕获方式,捕获所有在函数体内的所有的实体值,在lambda函数里默认都是const型,不能作为左值
    auto func1 = [=]()mutable->int{return a = 0;};//正确,因为lambda表达式中的mutable关键字可以取消其常属性。lambda默认表达式时const属性,在该属性下不能修改成员变量值。
    auto func = [&a]()->int{return a =1;};//正确,[&a]采用引用捕获方式,捕获变量a,在lambda函数里是变量,可以作为左值。
    auto fund = [&a]()->int{return a=11;};
    cout<<fund();


    //没有返回值时可以省略->return_type如:
    auto fun1 = []{printf("fffff\n");};
    fun1();//调用方式与函数类似,无参数
    auto fun2 = [](int a){printf("%d\n",a);};
    fun2(10);//有参数情况


    auto fun3 = []{return 1;};//可以忽略参数列表和返回类型
    auto fun4 = [](){return 0;};//可以忽略返回类型
    //auto fun5 = [=]->int{return a};//错误不能这么写,需写参数即使参数为空


    system("pause");


    return 0;
    }


    展开全文
  • C++ lambda表达式

    2020-07-28 17:15:41
    与函数类似,**lambda表达式**...《C++ Primer》中提到一个lambda表达式表示一个可调用的代码单元,可以将其理解为一个未命名的内联函数。本笔记参考《C++ Primer》,主要对C++ lambda表达式的用法进行一个简单的记录。

    与函数类似,lambda表达式也是一种可调用对象,但其可以定义在函数内部。《C++ Primer》中提到一个lambda表达式表示一个可调用的代码单元,可以将其理解为一个未命名的内联函数。本笔记参考《C++ Primer》,主要对C++ lambda表达式的用法进行一个简单的记录。

    用法简介

    当需要一个实现简单功能的可调用对象时,使用lambda表达式可以使得代码更为简洁。在一些泛型算法中可以直接传入lambda表达式自定义规则,比如sort第三个参数直接写个lambda表达式指定排序规则。

    lambda表达式的形式如下:

    [capture list](parameter list) -> return type {function body}

    [捕获列表](参数列表) -> 返回类型 {函数体}

    捕获列表用来放置在lambda表达式所在函数中定义的需要传入lambda表达式的局部变量。其余部分的含义与函数定义中对应的部分相同。不过lamdba必须使用尾置返回。lambda表达式中,参数列表和返回类型可以省略,捕获列表(尽管可能为空)和函数体必须存在。调用lambda表达式的方法也与调用普通函数一样,使用调用运算符()即可。

    简单示例

    简单的lambda表达式及调用示例如下,该示例捕获列表为空,没有参数列表和返回类型,函数体也仅仅是返回一个字符串。

    auto fun = [] { return "Hello world!"; };
    cout << fun() << endl;//输出Hello world!
    

    参数传递

    lambda表达式传递参数的方式也与函数类似,使用给定实参初始化形参,通常实参和形参类型必须匹配。下面给出一个示例。

    auto fun = [](const string &s1, const string & s2) { return s1 + ' ' + s2; };
    string s1 = "Hello";
    string s2 = "world";
    cout << fun(s1,s2) << endl;//输出Hello world
    

    捕获列表的使用

    通过捕获列表,我们可以在lambda表达式中使用lambda表达式所在函数中定义的局部变量。

    值捕获和引用捕获

    采用值捕获,被捕获的变量的值是在lambda创建时拷贝。下面的示例中,变量a在lambda创建时被捕获,完成了值的拷贝,因此当a的值改变后,再调用lambda发现并不起作用。

    int a = 1;
    auto fun = [a](int b) { return a + b; };
    int b = 1;
    cout << a << ' ' << b << endl;//输出1 1
    cout << fun(b) << endl;//输出2
    a += 1;
    cout << a << ' ' << b << endl;//输出2 1
    cout << fun(b) << endl;//输出2
    

    引用捕获的示例如下

    int a = 1;
    auto fun = [&a](int b) { return a + b; };
    int b = 1;
    cout << a << ' ' << b << endl;//输出1 1
    cout << fun(b) << endl;//输出2
    a += 1;
    cout << a << ' ' << b << endl;//输出2 1
    cout << fun(b) << endl;//输出3
    

    隐式捕获

    使用隐式捕获,就可以不显式列出要在lambda表达式要捕获的变量,取而代之的是让编译器通过lambda表达式中的代码来推断使用的变量。在捕获列表中写个=指示使用值捕获方式,写个&指示使用引用捕获方式。

    int a = 1;
    auto fun = [=](int b) { return a + b; };//[]中写个=,使用值捕获方式
    int b = 1;
    cout << a << ' ' << b << endl;//输出1 1
    cout << fun(b) << endl;//输出2
    a += 1;
    cout << a << ' ' << b << endl;//输出2 1
    cout << fun(b) << endl;//输出2
    
    int a = 1;
    auto fun = [&](int b) { return a + b; };//[]中写个&,使用引用捕获方式
    int b = 1;
    cout << a << ' ' << b << endl;//输出1 1
    cout << fun(b) << endl;//输出2
    a += 1;
    cout << a << ' ' << b << endl;//输出2 1
    cout << fun(b) << endl;//输出3
    

    可以混用显式捕获和隐式捕获。不过若隐式部分使用值捕获方式,则显式部分就不能用值捕获方式,反之,隐式部分使用引用捕获方式,则显式部分就不能用引用捕获方式。

    int a = 1;
    int b = 1;
    auto fun = [&, b](int c) { return a + b + c; };
    int c = 1;
    cout << fun(b) << endl;//输出3
    

    显式捕获和隐式捕获用同一种方式提示错误:
    在这里插入图片描述
    在这里插入图片描述
    当然,要是不用隐式捕获,捕获列表中各变量的捕获方式就随便写。

    尾声:就简单记录这么多,一般我自己也很少用到复杂的情况。

    展开全文
  • C++lambda表达式

    2018-08-12 16:24:36
    C++lambda表达式 lambda表达式的引入的主要目的是,让您能够使用表达式用作接受函数指针或函数符的函数的参数 for_each(numbers.begin(),numbers.end(),[&amp;count13](int x){ count13 += x % 13 == 0; ...

    C++lambda表达式

    lambda表达式的引入的主要目的是,让您能够使用表达式用作接受函数指针或函数符的函数的参数

        for_each(numbers.begin(),numbers.end(),[&count13](int x){ count13 += x % 13 == 0; });

    for_each是stl库的一个函数,最后一个参数可以接受函数符,函数指针以及lambda表达式

    lambda表达式的编写

    []省略了函数名称以及返回值 相当于使用decltype自动推断返回类型

    但值得注意的是,只有在函数完全由一条返回语句组成时,自动推断才生效,否则要使用返回类型后置

        auto mod2 = [] (int x) -> int { int y = x ; return y;} ;

    可以为lambda表达式指定一个名称,借此重复使用lambda表达式

    lambda表达式的名称也可以像普通函数一样使用

        auto mod3 = [] (int x) { return x%3 == 0 ; };
        int count1 = count_if(numbers.begin(),numbers.end(),mod3);
        int count2 = count_if(numbers.begin(),numbers.end(),mod3);
        bool result = mod3(3);
        cout << count1 <<" "<< count2 <<" "<< result <<" "<< endl;

    lambda的额外功能

    lambda可访问作用域内的任何动态变量

    把要捕获的变量放在[]内,可以按值或按引用访问变量
    按值访问时,直接输入变量名

        [count2] (int x) { return x%3 == 0 ; };

    按引用访问时,加上& ;

        /**
        *  [&count13]让lambda能够在其代码中使用count13
        *  由于count13是按引用捕获的,因此在lambda中对于count13的任何修改都会影响到原始count13
        **/
        count13 = 0;
        for_each(numbers.begin(),numbers.end(),[&count13](int x){ count13 += x % 13 == 0; });
        cout << "using lambda : count of numbers divisible by 13: " << count13 <<endl;

    [&]能够按引用访问作用域内的所有动态变量 ; [=]能够按值访问作用域内所有动态变量

    在这里&让lambda能够按照引用访问所有的动态变量

        count3=count13=0;
        for_each(numbers.begin(),numbers.end(),
        [&](int x) {count13 += x % 13 == 0; count3 += x % 3 ==0;});
        cout << "using lambda : count of numbers divisible by 3: " << count3 <<endl;
        cout << "using lambda : count of numbers divisible by 13: " << count13 <<endl;

    捕获和&=也可以组合起来使用,下式表示,按值访问ted并按引用访问其他所有动态变量

        [&,ted] ... {...}

    为什么使用lambda

    距离:一般来说,我们都希望定义位于使用附近的地方,这样在修改代码时,涉及的代码都在附近而不用翻阅很多页去找寻函数的定义的位置

    简洁:相对于函数符和函数,lambda表达式都要更简洁

    效率:可以在函数内部定义有名称的lambda,lambda的效率取决于编译器的实现方式

    功能:lambda表达式具有额外的功能(如上文所示)

    展开全文
  • C++ Lambda表达式

    2020-11-13 14:34:07
    C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。 ①函数对象参数; [],标识一个Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。...

    一、Lambda表达式的基本构成:

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

    ① 函数对象参数;

       [],标识一个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声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。

    ④ 函数返回值;

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

    ⑤ 是函数体;

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

     

    二、代码和测试输出

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public :
    	A(int aa, int bb) :a(aa), b(bb) {}
    
    	int b;
    
    	void test()
    	{
    		[this]() {
    			cout << this->b << endl;
    		
    		}();
    	}
    
    private:
    	int a;
    
    
    };
    
    //[](){} 是一个匿名函数
    //[](){}() 是匿名函数的调用
    
    void test1(void)
    {
    	cout << "test1:Lambda test[]:";
    
    	int a = 100;
    
    	[]() {
    		//不能使用任何对象
    		//cout << a << endl;
    		cout << "不能使用任何对象" << endl;
    	}();
    }
    
    void test2(void)
    {
    	cout << "test2 :Lambda test[=]:";
    
    	int a = 100;
    
    	[=]() {
    		 //函数体内可以使用Lambda所在作用范围内所有可见的局部变量
    		 //但是不能改变局部变量的值
    	     //a += 100;
    		 cout << a << endl;
    		
    	}();
    }
    
    void test3(void)
    {
    	cout << "test3:Lambda test[&]:" ;
    
    	int a = 100;
    
    	[&]() {
    		//函数体内可以使用Lambda所在作用范围内所有可见的局部变量
    		//但是不能改变局部变量的值
    		a += 100;
    		cout << a << endl;
    
    	}();
    
    	cout << a << endl;
    }
    
    void test4()
    {
    	cout << "test4:Lambda test[this]:" ;
    
    	A *p = new A(100,50);
    
    	p->test();
    
    	delete p;
    }
    
    void test5()
    {
    	cout << "test5: Lambda test mutable:";
    
    	//mutable声明,这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,
    	//可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。
    
    	int a = 100;
    
    	[a]()mutable
    	{
    		a += 100;
    		cout << a << endl;
    
    	}();
    
    	cout << a << endl; //a的值并没有改变 
    
    }
    
    void test6()
    {
    	cout << "test6:Lambda test return value:";
    	//->返回值类型,标识函数返回值的类型,当返回值为void,
    	//或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,
    	//这部分可以省略。
    
    	int res = []()->int {
    		return 100;
    	}();
    
    	cout << res << endl;
    
    }
    
    
    int main()
    {
    	test1();
    	cout << endl;
    	test2();
    	cout << endl;
    	test3();
    	cout << endl;
    	test4();
    	cout << endl;
    	test5();
    	cout << endl;
    	test6();
    	cout << endl;
    
    	return 0;
    }
    
    
    

     

     

    展开全文
  • c++ Lambda表达式

    2019-04-11 20:15:31
    Lambda表达式(C++11引入) Lambda语法 Lambda表达式是一种能够捕获作用域中变量的无名函数对象,也是构造闭包的方式。 常见语法如下: [ captures ] ( params ) -> ret { body } 其中captures为捕获的变量列表,...
  • C++ Lambda 表达式

    2020-03-16 11:44:25
    声明Lambda表达式 [capture list] (params list) mutable exception-> return type { function body } 各项具体含义如下 capture list:捕获外部变量列表 params list:形参列表 mutable指示符:用...
  • C++Lambda表达式

    2019-07-25 23:06:33
    C++11引入的Lambda表达式可以快速的得到某些只调用1次的函数,可以理解成匿名函数,方便阅读时直接了解到调用函数的功能。 注意在例如cb、dev中编译设置要有-stdc++11,因为这是11的标准,这个表达式可以结合着auto...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,990
精华内容 1,596
关键字:

c++lambda表达式

c++ 订阅