设为首页 加入收藏

TOP

lambda表达式(一)
2023-07-23 13:39:09 】 浏览:130
Tags:lambda

lambda表达式

匿名函数(lambda函数)

匿名函数(英文名:lambda)就是没有名字的函数。最简单的匿名函数是[]{},它没有参数也没有返回值。在匿名函数中,[]里面用来捕获函数外部的变量,而()里面就是匿名函数的参数,{}里面就是函数的执行代码。

匿名函数也称lambda函数lambda表达式

示例:

#include <iostream>
using namespace std;
int main()
{
    //定义函数,使用auto来自动获取function的类型
    auto function = [](){ cout << "Hello world!"; };	
    fuction();	//调用函数
    return 0;
}

lambda表达式的声明

lambda表达式完整声明形式如下:

[capture list](params list)mutable exception->return type{function body}

具体含义如下:

  • capture list:捕获外部变量列表,总是出现在lambda表达式的起始位置,编译器根据[]来判断接下来的代码是否为lambda表达式

  • params list:形参列表

  • mutable:指示符,用来表示是否可修改捕获的变量,使用mutable指示符时,参数列表不能省略,即使为空

  • exception:异常设定,用于指定函数抛出的异常,如抛出整数类型的异常,可以使用 throw(int)

  • return type:返回类型,返回类型可以省略,但编译器会推断出lambda表达式的返回类型:(1)如果function body中存在return语句,则表达式的返回类型由return语句的返回类型决定;(2)如果function body中没有return语句,则返回类型为void

  • function body:函数主体

    同时,也可以省略其中的某些成分来声明“不完整”的lambda表达式
    常见的几种如下:

1. [capture list](params list)->return type{function body}
2. [capture list](params list){funtion body}
3. [capture list]{fuction body}

实例:

#include <iostream>
#include <vector>
#include <time.h>
#include <algorithm>
using namespace std;

int main()
{
    srand(time(0));
    vector<vector<int>> nums(10, vector<int>(2, 0));
    for (int i = 0; i < nums.size(); i++)
    {
        nums[i][0] = i;
        nums[i][1] = rand() % 10;
    }
    sort(nums.begin(), nums.end(), [](vector<int> &a, vector<int> &b) -> bool
         { return a[1] < b[1]; });
    for (vector<int> &num : nums)
    {
        cout << num[0] << '(' << num[1] << ") ";
    }
    return 0;
}
//结果
//4(2) 5(2) 9(2) 0(5) 8(5) 1(7) 3(7) 7(8) 2(9) 6(9)

使用STL中的sort函数时,可以为其提供一个谓词函数作为排序的依据,这里使用lambda表达式作为谓词函数,方便简洁

lambda表达式具体用法

下面对lambda表达式中各项的具体用法进行介绍

捕获外部变量

lambda表达式可以使用其可见范围内的外部变量,但必须声明哪些外部变量可以被该lambda表达式使用。lambda表达式通过在最前面的方括号[] 来指明内部可以访问的外部变量,这一过程也称lambda表达式“捕获了”外部变量

  • 捕获列表可由多个捕获项组成,以逗号隔开,需要注意捕获项不能重复,否则会编译错误。比如[=,num],=已经捕获过num了
  • 只能捕获当前作用域的局部变量,捕获作用域外的局部变量或非局部变量都会报错
  • lambda表达式之间不能赋值

类似参数传递方式(值传递、引用传递、指针传递),在lambda表达式中,外部变量的捕获方式也有值捕获引用捕获隐式捕获

1. 值捕获

值捕获与参数传递中的值传递类似,被捕获的变量在lambda表达式创建时通过值拷贝的方式传入,随后对该变量的修改不会影响lambda表达式

需要注意,以值捕获外部变量,在lambda表达式函数体中不能对该外部变量的值进行修改,即值捕获具有常性

示例:

#include <iostream>
using namespace std;

int main()
{
    int num = 17;
    auto func = [num]{cout << num << endl;};
    num = 19;
    func();
    return 0;
}
//结果
//17

这个例子中lambda表达式在创建时捕获了num变量,并在创建后在外部对num的值进行了修改,在使用lambda表达式时输出的仍是num的初始值,体现了lambda表达式是在创建时获得了num变量的值

2. 引用捕获

使用引用捕获一个外部变量,只需在捕获变量前加上一个引用说明符&,引用捕获不具有常性

示例:

#include <iostream>
using namespace std;

int main()
{
    int num = 17;
    auto func = [&num]{cout << num << endl;};
    num = 19;
    func();
    return 0;
}
//结果
//19

3. 隐式捕获

值捕获和引用捕获都需要我们在捕获列表中显示地列出lambda表达式中使用的外部变量。

此外,我们还可以让编译器根据函数体中的代码来推断需要捕获哪些外部变量,这种方式称为隐式捕获。隐式捕获有两种方式,分别是[=]和[&],[=]表示以值捕获,[&]表示以引用捕获

隐式值捕获示例:

#include <iostream>
using namespace std;

int main()
{
    int num1 = 17 , num2 = 21;
    auto func = [=]{cout << num1 << ',' << num2 << endl;};
    num1 = 19;
    num2 = 27;
    func();
    return 0;
}
//结果
//17,21

隐式引用捕获示例:

#include <iostream>
using namespace std;

int main()
{
    int num1 = 17 , num2 = 21;
    auto func = [&]{cout << n
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇__int128:懒人的福音 下一篇洛谷P3654 First Step题解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目