首页 > 编程语言 >C++温故补缺(二):lambda函数

C++温故补缺(二):lambda函数

时间:2023-03-20 23:25:15浏览次数:88  
标签:function 函数 int auto C++ 温故 变量 lambda

Lambda函数

参考:CSDN

C++11开始,提供了对匿名函数的支持,成为Lambda函数(表达式)

通常,lambda函数用于封装传递给算法或异步方法的几行代码,对应不需要复用,且短小的函数,使用lambda函数可以增加代码的可读性

格式:

auto function=[capture list](parameters) mutable throw()->return-type {statement}

一般用一个auto变量来接收,然后通过这个变量名function(paramenters)调用,也可以直接附上参数,不需要auto变量名

[capture list](paramenters) mutable throw()->return-type {statement}(real paramenters)

例如:

auto function=[a,&b](int x) mutable ->int {return a+b+x;};
int m=function(20);
//another
int m=[a,&b](int x) mutable ->int {return a+b+x;}(20);
  • 捕获列表:在C++规范中也称Lambda导入器,[]就是lambda引出符,编译器根据该引出符判断接下来的代码是否lambda函数,捕捉列表能捕捉上下文中的变量,供Lambda函数使用,也就相当于在函数中调用函数外的变量.
  • 参数列表:和普通函数的参数列表一致,如果不需要传递参数,则可以连同()一同省略
  • 可变规格:mutable修饰符,默认情况下lambda函数总是一个const函数,mutable可以取消其常量性,如果使用了mutable,则参数列表不可省略
  • 异常说明:用来抛出异常
  • 返回类型:声明函数的返回类型,如果不需要返回值,则可以连同符号->一起省略,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推到
    • int a; return a+2;编译器就能自动推导返回值类型为int
  • lambda函数体:和普通函数别无二致,除了传入的参数,还可以使用捕获的变量

捕获列表

捕获列表就是lambda以值传递或引用传递的方式调用上下文的变量

  • []表示不捕获任何变量
auto function=[]{std::cout<<"Hello";};
function();

这是一个简单的lambda例子,它的功能是输出"hello"

  • [var]表示值传递的方式捕获变量var
int num=100;
auto function=[num]{std::cout<<num;};
function();

捕获就是在lambda表达式内部调用外面的变量,值传递相当于普通函数的值传递形式

  • [=]表示值传递方式捕获父作用域的所有变量,包括this
int a=100;
float b=1.2;
auto function=[]{cout<<a<<endl<<b;};
function();
  • [&var]表示引用传递捕捉变量var
int a=100;
auto function=[]{a++;cout<<a;};
function();

也就是能在lambda表达式中改变变量的值

  • [&]表示引用传递捕捉父作用域的所有变量
int a=100;
float b=1.2;
auto fnction=[]{a++;
                b+=2.3;
                cout<<a<<endl<<b;};
function();
  • [this]表示值传递方式捕捉当前的this指针
#include<iostream>
using namespace std;

class test{
    public:
        void sayHello(){
            cout<<"hello"<<endl;
        }
        void lambda(){
            auto function=[this]{this->sayHello();};
            function();
        }
};
int main(){
    test t1;
    t1.lambda();
}
  • [=,&]拷贝和引用混合

    • [=,&a,&b]:以值传递的方式捕捉其他所有变量,以引用方式捕捉a,b

    • [&,a,this]:以值传递捕捉a和this,其他用引用方式

  • 捕捉列表不允许变量重复传递,如

    • [=,a]:已经捕捉了所有变量,重复捕捉a,会报错

    • [&,&this]:也是会报错

参数列表

格式和使用都和普通函数无二致

auto function=[](int x,int y){return x+y};
int a=function(100,200);

可变规格mutable

通过值传递方式捕获的变量在lambda中默认是const类型,只能输出,不能改变,使用mutable可以使其可变,但是只能在lambda中短暂使用,并不能影响到父作用域的变量

int a=1;
auto function=[a]() mutable {a++;};
function();

这时参数列表()不能省略,可以使空的参数列表,但()不能省

lambda的优缺点

优点:

  • 可以直接在需要调用函数的位置定义短小精简的函数,不需要预先定义好函数

  • 可以使代码结构更紧凑,因为调用的函数的定义就在旁边,不用向前后向后找,可读性更好

缺点:

  • 增加了阅读代码的难度

  • 无法复用

工作原理

编译器会把一个Lambda表达式生成一个匿名类的匿名对象,并在类中重载函数调用运算符,实现了一个operator()方法

auto print=[]{cout<<"hello"<<endl;};

编译器会把它翻译为下面的代码:

class print_class{
    public:
        void operator()(void) const{
            cout<<"hello"<<endl;
        }
};
auto print=print_class();

标签:function,函数,int,auto,C++,温故,变量,lambda
From: https://www.cnblogs.com/Tenerome/p/cppreview2.html

相关文章

  • C++温故补缺(九):C++多态
    C++多态继承和派生当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态如:shape类被派生为两个类:Rectangle和Triangle#include<iostream>usingnamespacestd......
  • C++温故补缺(八):运算符重载和函数重载
    运算符重载和函数重载重载是c++多态性的一大体现,重载运算符是给运算符添加新的定义,使之前不能运算的对象变得可运算,且一般和运算符的意义相似.函数重载主要是同名函数......
  • C++温故补缺(七):;类的访问控制和继承
    类的访问控制和继承类的静态成员类的静态成员用关键字static修饰,类似静态变量或静态函数,也是有共享的概念类的静态变量:静态变量在类的所有对象中共享,不能再类的定......
  • C++温故补缺(六):友元函数、内联函数和this指针
    友元函数、内联函数和this指针友元函数友元函数是定义在类的外部,但有权访问类的所有私有(private)和保护(protectd)成员.友元函数的原型在类的定义中出现,但它并不是类......
  • C++温故补缺(十五):多线程
    多线程参考:CSDN,知乎传统C++(C++11之前)中并没有引入线程的概念,如果想要在C++中实现多线程,需要借助操作系统平台提供的API,如Linux的<pthread.h>,或windows下的<windows.......
  • C++温故补缺(十四):信号处理
    信号处理信号是由操作系统传给进程的中断,能够提前终止一个程序。在Unix,Linux,MacOS或Windows系统上,都可以通过Ctrl+C产生中断。下面是可以在程序中被捕获的信号,并且可......
  • C++温故补缺(十三):模板
    C++模板模板是泛型的基础,泛型编程就是一种独立于任何特殊类型的方式编写代码。模板就是创建泛型类或泛型函数的蓝图。STL库中的几个数据结构(vector,list,map等)以及算法......
  • C++温故补缺(十二):动态内存
    C++动态内存同C,C++中也是有堆和栈的概念。栈是函数内部声明的所有变量都所占用空间,堆是程序中未使用的内存,在程序运行期间可用于动态分配。同样也有alloc()分配内存,新增......
  • C++温故补缺(十一):异常
    异常处理参考:cnblogs异常和错误(bug)异常:是程序开发过程中必须考虑的一些特殊情况,是程序运行时可以预料的执行分支。异常是不可以避免的,如0除问题,数组越界问题,文件不存在......
  • C++温故补缺(十):C++文件读写和流
    C++文件和流C++文件的读写流用的是fstream库,它定义了三个新的数据类型:数据类型描述ofstream该数据类型表示输出文件流,用于创建文件并向文件写入信息。ifstr......