C++ lambda表达式写法

lambda表达式,也叫作匿名函数。

1示例1

class Solution {
public:
    int numWays(int n, vector<vector<int>> &relation, int k) {

        unordered_map<int, vector<int>> h;
        for(int i = 0; i < relation.size(); i++)
        {
            int a = relation[i][0];
            int b = relation[i][1];
            h[a].push_back(b);
        }

        int res = 0;

        //lambda表达式
        //[&]表示 任何被使用到的外部变量都隐式地以引用方式加以引用 比如res, h
        function<void(int, int)> dfs = [&](int person, int step)
        {
            if(step == k)
            {
                if(person == n-1) res++;
                return;
            }

            for(int i = 0; i < h[person].size(); i++)
                dfs(h[person][i], step+1);

        };

        dfs(0, 0);

        return res;
    }
};


2示例2

class Solution {
public:
    int numOfMinutes(int n, int headID, vector<int>& manager, vector<int>& informTime) {
        // 建立一个从 manager[i] 到 i 的有向图
        unordered_map<int, vector<int>> g;
        for (int i = 0; i < n; i++) {
            g[manager[i]].emplace_back(i);
        }

        // 定义一个 dfs 函数,遍历从 headID 开始的子树
        function<int(int)> dfs = [&](int cur) -> int {
            int res = 0;
            // 遍历当前节点的所有子节点,计算从子节点到当前节点的时间
            for (int neighbor : g[cur]) {
                res = max(res, dfs(neighbor));
            }
            // 加上当前节点到其上级节点的时间
            return informTime[cur] + res;
        };

        // 返回从 headID 到其所有子节点的最大时间
        return dfs(headID);
    }
};

其中function<int(int)>表示啥意思?

function<int(int)> 是一个函数类型,表示它返回一个 int 类型的结果,接受一个 int 类型的参数。它可以用于声明和定义函数对象、函数指针等等。在这个函数中,使用 function<int(int)> 作为参数类型是为了接受传入 dfs 函数的函数参数(即回调函数)。通过这种方式,我们可以在运行时传入不同的函数,并根据不同的函数来执行不同的操作。

其中dfs = [&](int cur) -> int是什么意思?

dfs = [&](int cur) -> int 是一个 lambda 表达式。其中 [&] 表示使用 lambda 表达式当前作用域中的所有变量,使用引用捕获,保证在调用时可以访问到外部作用域中的所有变量。int cur 是参数列表,表示 dfs 有一个参数 cur,类型为 int

-> int 表示这个 lambda 表达式将会返回一个 int 类型的结果。在这个 lambda 表达式中,cur 是传入的参数,dfs 函数的递归过程就是不断改变 cur 的值,直到满足递归结束的条件才返回最终结果。

3捕获类型

C++中lambda表达式中的捕获类型有以下几种:

  1. 值捕获([]):在lambda表达式中,通过[]捕获外部变量的值,而不是引用外部变量。使用值捕获时,lambda表达式内部的变量会拷贝一份外部变量的值,并存储在lambda对象内部,即不会改变外部变量的值。

  2. 引用捕获([&]或[&x]):引用捕获可以让lambda表达式访问包含它的函数所定义的变量,并引用这些变量。在引用捕获的情况下,lambda内部变量会是外部变量的别名,即可以修改外部变量的值。

  3. this指针捕获([this]或[=]):类成员函数中,lambda表达式可以捕获this指针。如果使用[this],lambda表达式内部变量也是外部变量的别名,并可以修改它们的值;如果使用[=],则表示以值的方式捕获所有类成员变量

  4. 复合捕获([&,x]或[=,&y]):复合捕获可以同时使用值捕获和引用捕获或者同时指定多个变量进行捕获,其中&表示引用捕获,=表示值捕获。在使用复合捕获时,捕获列表中的项可以按任意顺序排列,但捕获列表始终要出现在->或{}之前。

以上是C++中lambda表达式中的捕获类型。需要注意的是,如果使用捕获列表,必须以的形式传递参数。例如:

auto lambdaFunc = [&x](int y){return x + y;};

以下是一个值捕获的示例:

#include <iostream>

int main() {
    int x = 10;
    auto lambdaFunc = [x]() {
        std::cout << "x is " << x << std::endl;
    };
    x = 20;
    lambdaFunc(); // 输出:x is 10
    return 0;
}

在这个示例中,我们定义了一个整型变量x,并将其初始化为10。然后我们定义了一个lambda表达式lambdaFunc,它使用值捕获来捕获变量x的值。在lambda表达式内部,我们输出变量x的值。接着我们将变量x的值修改为20。最后,我们调用lambdaFunc函数,它输出的结果是x is 10,说明在lambda表达式中捕获的变量x的值没有被改变。这是因为在值捕获中,内部变量会拷贝一份外部变量的值,并存储在lambda对象内部,即不会改变外部变量的值。

以下是一个引用捕获的示例:

#include <iostream>

int main() {
    int x = 10;
    auto lambdaFunc = [&x]() {
        std::cout << "x is " << x << std::endl;
    };
    x = 20;
    lambdaFunc(); // 输出:x is 20
    return 0;
}

在这个示例中,我们也定义了一个整型变量x,并将其初始化为10。然后我们定义了一个lambda表达式lambdaFunc,它使用引用捕获来捕获变量x的值。在lambda表达式内部,我们输出变量x的值。接着我们将变量x的值修改为20。最后,我们调用lambdaFunc函数,它输出的结果是x is 20,说明在引用捕获中,内部变量的值是外部变量的引用,因此会跟着外部变量的值改变而改变。需要注意的是,在使用引用捕获时,需要确保外部变量在lambda表达式执行期间存在,并且保证其值不会变成无效值。

以下是一个this指针捕获的示例:

#include <iostream>

class MyClass {
public:
    void printData() {
        auto lambdaFunc = [this]() {
            std::cout << "data is " << data << std::endl;
        };
        lambdaFunc();
    }
private:
    int data = 10;
};

int main() {
    MyClass obj;
    obj.printData(); // 输出:data is 10
    return 0;
}

在这个示例中,我们定义了一个名为MyClass的类,它包含私有成员变量data,并定义了一个公有成员函数printData。在printData函数内部,我们定义了一个lambda表达式lambdaFunc,使用this指针捕获了当前对象的实例,并在lambda表达式内部输出了成员变量data的值。接着我们在printData函数末尾调用lambdaFunc函数,它输出的结果是data is 10,说明在使用this指针捕获时,lambda表达式可以访问当前对象中的所有成员变量和成员函数。需要注意的是,在使用this指针捕获时,需要确保lambda表达式所使用的对象在lambda表达式执行期间存在并且保证其值不会变成无效值。

以下是一个复合捕获的示例:

#include <iostream>

int main() {
    int a = 10, b = 20;
    auto lambda = [&a, &b]() {
        std::cout << "a in lambda: " << a << std::endl;
        std::cout << "b in lambda: " << b << std::endl;
        a += 5;
        b += 10;
        std::cout << "a in lambda after modification: " << a << std::endl;
        std::cout << "b in lambda after modification: " << b << std::endl;
    };
    lambda();
    std::cout << "a in main: " << a << std::endl;
    std::cout << "b in main: " << b << std::endl;
    return 0;
}

在这个示例中,我们定义了两个整型变量a和b,并定义了一个lambda表达式lambda,使用复合捕获[&a, &b],捕获了变量a和b的引用。在lambda内部,我们首先打印了捕获的变量a和b的值,然后分别将它们的值增加了5和10,并在控制台上打印了输出信息。在最后,我们在main函数内部打印了变量a和b的值,可以发现它们的值分别增加了5和10,说明在复合捕获中,被捕获的变量的引用在内部lambda表达式的修改过程中,同时也会影响到外部lambda表达式中捕获的变量的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YMWM_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值