C/C++教程

C++11 lambda表达式

本文主要是介绍C++11 lambda表达式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

C++11 lambda表达式

  • 1 什么是lambda表达式
  • 2 什么是lambda组成部分
    • 2.1 []捕获
      • 2.1.1 捕获形式:
      • 2.1.2 []不捕获任何外部变量:
      • 2.1.2 修改非mutable值捕获:
      • 2.1.3 重复捕获:
      • 2.1.4 混合捕获:
    • 2.2 参数列表
    • 2.3 mutable
    • 2.4 noexcep/throw()
  • 3 lambda优点
  • 4 lambda可以直接使用无需捕获的变量类型

1 什么是lambda表达式

是一个闭包;是一个能够在作用域中捕获变量的匿名函数对象。

2 什么是lambda组成部分

在这里插入图片描述
1、捕获:可以为0或者多个分割列表
2、参数列表:可有可无
3、mutable: 可变规范可有可无
4、throw(): 异常规范 可有可无
5、返回类型:可有可无
6、lambda本地

2.1 []捕获

2.1.1 捕获形式:

  1. [] : 不捕获任何外部变量
  2. [=] : 以值的形式捕获所有外部变量
  3. [var1, var2, … ] : 以值的形式捕获多个外部变量(变量用逗号分)
  4. [&var1, &var2,…] : 以引用的形式捕获多个外部变量(变量用逗号分割)
  5. [&] : 以引用的形式捕获所有外部变量
  6. [=,&var1] :以引用形式捕获var1,其余外部变量以值的形式捕获
  7. [&,var1] :以值形式捕获var1,其余外部变量以引用的形式捕获
  8. [this] : 以值的形式捕获this指针

2.1.2 []不捕获任何外部变量:

#include <algorithm>
#include <iostream>

using namespace std;

// 测试不捕获任何变量
void fun1(){
   int var1 = 1;
   int var2 = 2;
   []() noexcept {  
       int i = var1;
       int j = var2;
       cout << i << " " << j << endl;
   };
}

int main(){
   fun1();
   return 0;
}

编译报错:
lambda不捕获变量,内部就不能使用。
在这里插入图片描述

2.1.2 修改非mutable值捕获:

#include <algorithm>
#include <iostream>

using namespace std;

//测试修改值捕获
void fun2(){
    int var1 = 1;
    int var2 = 2;
    [var1, var2]() noexcept {  
        int i = var1;
        int j = ++var2;
        cout << i << " " << j << endl;
    };
}
int main(){
    fun2();
    return 0;
}

编译报错:
var2是值捕获不能被修改
在这里插入图片描述

2.1.3 重复捕获:

#include <algorithm>
#include <iostream>

using namespace std;

//重复捕获
void fun3(){
    int var1 = 1;
    int var2 = 2;
    [=, var2]() noexcept {  
        int i = var1;
        int j = var2;
        cout << i << " " << j << endl;
    }();
}
int main(){
    fun3();
    return 0;
}

编译告警:
显示的var值拷贝和默认的全值拷贝冗余
在这里插入图片描述

2.1.4 混合捕获:

#include <algorithm>
#include <iostream>

using namespace std;


void fun4(){
    int var1 = 1;
    int var2 = 2;
    int var3 = 3;
    //值捕获
    [=]() noexcept {  
        int i = var1;
        int j = var2;
        cout << "i=" << i << " " << "j=" << j << endl;
    }();

    //引用捕获,修改外部变量值i,j的值
    [&]() noexcept {  
        int i = ++var1;
        int j = ++var2;
        cout << "i=" << i << " " << "j=" << j << endl;
    }();

    //var1引用捕获,var2,var3值捕获
    [=, &var1]() noexcept {  
        int i = ++var1;
        int j = var2;
        int k = var3;
        cout << "i=" << i << " " << "j=" << j << 
        " " << "k=" << k << endl;
    }();
}

int main(){
    fun4();
    return 0;
}

输出结果:
在这里插入图片描述

2.2 参数列表

Lambda表达式中传递参数和有名函数参数列表一样

2.3 mutable

#include <algorithm>
#include <iostream>

using namespace std;


void fun6(){
    int var1 = 1;
    int var2 = 2;
    [=]() mutable noexcept {  
        int i = ++var1;
        int j = ++var2;
        cout << i << " " << j << endl;
    }();
}

int main(){

    fun6();
    return 0;
}

输出结果:
在这里插入图片描述

2.4 noexcep/throw()

noexcept == throw()  == noexcept(true)
noexcept目的是会防止异常扩散。如果出现异常,会调用terminate()->abort()结束程序。
#include <algorithm>
#include <iostream>

using namespace std;


void fun7(){
    int var1 = 1;
    int var2 = 2;
    [=]() mutable noexcept {  
        int i = ++var1;
        int j = ++var2;
        cout << i << " " << j << endl;
        throw(5);
    }();
}

int main(){

    fun7();
    return 0;
}

运行结果崩溃

在这里插入图片描述

3 lambda优点

1、简洁
2、距离执行代码近,便于阅读理解代码。
3、可以捕获作用域中的任何变量

4 lambda可以直接使用无需捕获的变量类型

全局变量,thread_local 变量,static变量都是可以直接使用,无需捕获。

#include <algorithm>
#include <iostream>

using namespace std;
int g_a = 90;
thread_local unsigned int rage = 77;

void fun8(){
    static int var1 = 1;
    
    const int d1 = 5;
    []() mutable noexcept {  
        int j = ++var1;
        ++g_a;
        ++rage;
        cout << "g_a:" << g_a << " "<< " j:" << j << " "<< " rage:" << rage << endl;
        cout << "d1:" << d1 << endl;
    }();
}


int main(){

    fun8();
    return 0;
}

输出结果:
在这里插入图片描述

这篇关于C++11 lambda表达式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!