【C++面试】Lambda表达式底层:编译器如何生成仿函数?

大家好,今天我们来聊聊 C++ 中的 Lambda 表达式。Lambda 在 C++11 中引入,它提供了一种定义匿名函数对象的便捷方式,常用于回调、泛型编程等场景。在面试中,Lambda 的实现原理常常被问到,因为它涉及了C++的很多核心概念。

我们来看一个 Lambda 表达式的例子:

auto lambda = [value = 10](int x) mutable {
    ++value;
    return x + value;
};

这个Lambda表达式做了什么?

  1. 它捕获了一个变量 value,并将其初始化为 10(注意:这里使用了 C++14 的初始化捕获,因此不需要外部有一个变量 value)。
  2. 它接受一个参数 x,并且由于使用了 mutable,可以在函数体内修改捕获的 value。
  3. 返回 x 和 value 的和。

但是,Lambda 表达式真的只是一个函数吗?不,实际上它是一个仿函数(functor)。编译器会为我们生成一个匿名的类,这个类重载了 operator( )。上面的 Lambda 表达式大致会被编译器转换成下面的类:

class __lambda_1 {
    int value;  // 捕获的变量
public:
    __lambda_1(int v) : value(v) {}  // 构造函数,用捕获的值初始化成员变量

    // 注意:因为 Lambda 使用了 mutable,所以 operator() 不是 const 的
    int operator()(int x) {
        ++value;  // 可以修改成员变量
        return x + value;
    }
};

然后,我们使用Lambda的地方,实际上是在使用这个类的对象:

auto lambda = __lambda_1(10); 

这样,我们就明白了 Lambda 的底层实现。接下来,我们看看捕获列表:

  • 如果是值捕获,则成员变量是值类型,在构造时拷贝。
  • 如果是引用捕获,则成员变量是引用类型,注意引用的生命周期

另外,如果没有使用mutable,则operator()是const的,不能修改值捕获的变量。

理解 Lambda 的仿函数本质,有助于我们更好地使用它,并理解其性能开销(比如,值捕获会涉及拷贝,引用捕获则要注意悬垂引用)。

总结一下,Lambda 表达式是 C++ 中非常强大的特性,但它的底层实现并不神秘。掌握其仿函数本质,能够帮助我们在面试中游刃有余,也能写出更高效的代码。

如果你有更多关于 Lambda 的问题,或者想了解其他 C++ 特性,欢迎在评论区留言。我们下期再见!

全部评论
这回lambda底层清楚多了
2 回复 分享
发布于 今天 01:31 北京
欢迎订阅专栏《C++/嵌入式开发秋招面经》:https://www.nowcoder.com/creation/manager/columnDetail/MKaoll
2 回复 分享
发布于 今天 01:29 河北
你是我见过最帅的牛客男孩
点赞 回复 分享
发布于 今天 13:47 北京

相关推荐

📝首先把岗位JD丢给ai,进行摸底和避雷。prompt:1️⃣该公司是一家xxxx公司,这是xxx岗位的JD。请阐述该岗位的核心指责需求和候选人必须具备的能力,以及有哪些潜在的工作“风险”📝然后把自己的简历、作品集丢给AI,prompt:2️⃣假设你是该岗位面试官或HR,请根据岗位JD和简历作品集综合评估该候选人是否符合岗位需求,符合的点有哪些?给出具体原因和结论。3️⃣假设你是该岗位面试官或HR,你觉得该候选人能力上还有哪些欠缺,有哪些点需要重点考核?4️⃣假设你是该岗位面试官或HR,面试时会如何提问以挖掘候选人的真实能力?请扮演一位极度挑剔甚至带有偏见的业务主管,针对该候选人简历中比较契合的经历进行质疑,并给出三个最难回答的压力面问题。5️⃣请对比JD里的行业术语与候选人简历中的表达、作品集的呈现,指出匹配但表述不够契合的地方,并提供修改建议,让整体契合度能更好的体现。📝综合以上来验证自己和该岗位的匹配度,以及可能存在的、需要主动优化的岗位适配的gap,以及提前准备好有哪些需要具体应对的问题,最后进行简历和作品集的优化📞然后和豆包打电话实战练习(豆包会针对每个问题+你的回复,快速概括总结你说过的观点,给你一个回答该问题的标准答案),事后复盘优化自己的回答思路
找工作,你都让AI帮你做...
点赞 评论 收藏
分享
评论
2
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务