当前位置: 首页 > news >正文

【c++】:Lambda 表达式介绍和使用

C++17 对 Lambda 表达式进行了多项重要扩展,使其功能更强大、使用更灵活。Lambda 表达式是一种匿名函数,用于简化代码中的回调、排序、算法参数等场景。以下从 基础语法C++17 新增特性实际应用 三个维度详细讲解:

一、Lambda 表达式基础语法

Lambda 表达式的核心结构如下(C++11 起支持):

[capture-list](parameters) mutable noexcept -> return-type {// 函数体
}
  • 捕获列表(capture-list:定义 Lambda 外部变量的访问方式(如按值捕获 [x]、按引用捕获 [&y])。
  • 参数列表(parameters:与普通函数参数类似,C++14 起支持 auto 自动推导参数类型。
  • mutable:允许修改按值捕获的变量(默认按值捕获为 const)。
  • noexcept:声明函数不抛出异常。
  • 返回类型(return-type:可省略,由编译器自动推导(C++11 起)。

二、C++17 对 Lambda 的核心增强

C++17 新增了多项特性,解决了之前版本的限制,主要包括:

1. ** constexpr Lambda(常量表达式 Lambda)**
  • 特性:Lambda 表达式可在编译期执行,支持用于 constexpr 变量初始化、模板参数等编译期场景。
  • 语法:无需显式声明 constexpr,编译器会自动判断 Lambda 是否满足常量表达式要求(若函数体符合 constexpr 规则)。
  • 示例
    #include <iostream>int main() {// C++17 中,满足条件的 Lambda 自动为 constexprauto add = [](int a, int b) { return a + b; };// 编译期计算(需编译器支持 C++17)constexpr int sum = add(3, 5);  // sum = 8(编译期确定)std::cout << sum << std::endl;return 0;
    }
    
  • 限制:函数体只能包含编译期可执行的代码(如无动态内存分配、无虚函数调用等)。
2. 捕获 *this(按值捕获当前对象)
  • 问题背景:C++11/14 中,[this] 按引用捕获当前对象,若 Lambda 生命周期超过对象生命周期,会导致悬垂引用。
  • C++17 解决方案[*this] 按值捕获当前对象的副本,避免悬垂引用。
  • 示例
    #include <iostream>
    #include <memory>struct MyClass {int x = 10;auto getLambda() {// 按值捕获当前对象(*this 是对象的副本)return [*this]() { std::cout << "x = " << x << std::endl;  // 访问副本的 x};}
    };int main() {auto lambda = [](){MyClass obj;return obj.getLambda();  // obj 生命周期结束,但 Lambda 持有副本}();lambda();  // 输出:x = 10(安全访问副本)return 0;
    }
    
3. 模板化 Lambda(泛型 Lambda 增强)
  • 特性:C++14 已支持 auto 作为参数类型(泛型 Lambda),C++17 进一步允许显式模板参数列表,支持更复杂的泛型逻辑。
  • 语法[]<template-params>(params) { ... }
  • 示例
    #include <iostream>
    #include <vector>
    #include <list>int main() {// 显式模板参数的 Lambda(C++17 新增)auto printSize = []<typename T>(const T& container) {std::cout << "Size: " << container.size() << std::endl;};std::vector<int> vec = {1, 2, 3};std::list<double> lst = {1.1, 2.2};printSize(vec);  // 输出:Size: 3(T 推导为 vector<int>)printSize(lst);  // 输出:Size: 2(T 推导为 list<double>)return 0;
    }
    
  • 优势:比 auto 参数更灵活,支持模板特化、模板参数约束(C++20 进一步增强)等。
4. Lambda 在非类型模板参数中使用
  • 特性:C++17 允许 Lambda 作为非类型模板参数(需满足 constexpr 要求)。
  • 示例
    #include <iostream>// 模板接受 Lambda 作为参数
    template <auto Lambda>
    void callLambda() {Lambda();  // 调用传入的 Lambda
    }int main() {// 传递 constexpr Lambda 作为模板参数callLambda<[](){ std::cout << "Lambda called!\n"; }>();  // 输出:Lambda called!return 0;
    }
    
5. 捕获初始化(初始化捕获的增强)
  • 特性:C++14 已支持初始化捕获(如 [x = 10](){ ... }),C++17 允许捕获中使用 auto 自动推导类型,简化代码。
  • 示例
    #include <iostream>
    #include <string>int main() {std::string s = "hello";// 初始化捕获 + auto 推导(C++17 允许)auto lambda = [str = std::move(s)]() {  // str 类型自动推导为 stringstd::cout << str << std::endl;};lambda();  // 输出:helloreturn 0;
    }
    

三、C++17 Lambda 的实际应用场景

1. 编译期计算

利用 constexpr Lambda 实现编译期逻辑,提升运行时效率:

constexpr auto factorial = [](int n) {int res = 1;for (int i = 2; i <= n; ++i) res *= i;return res;
};constexpr int f5 = factorial(5);  // 120(编译期计算)
2. 安全捕获对象

使用 [*this] 避免对象生命周期问题,尤其在异步编程中:

#include <future>struct Task {int value = 5;auto asyncTask() {// 按值捕获 this,确保异步执行时对象已销毁也安全return std::async(std::launch::async, [*this]() {return value * 2;  // 使用对象副本的 value});}
};int main() {auto future = [](){Task t;return t.asyncTask();  // t 销毁,但 Lambda 持有副本}();std::cout << future.get() << std::endl;  // 输出:10return 0;
}
3. 泛型算法适配

结合模板化 Lambda 简化泛型代码,适配不同容器或数据类型:

#include <algorithm>
#include <vector>// 通用过滤函数,接受 Lambda 作为过滤条件
template <typename Container, typename Filter>
auto filter(const Container& c, Filter f) {Container res;std::copy_if(c.begin(), c.end(), std::back_inserter(res), f);return res;
}int main() {std::vector<int> nums = {1, 2, 3, 4, 5, 6};// 模板化 Lambda 作为过滤条件(同时支持奇偶数判断)auto isEven = [](auto x) { return x % 2 == 0; };auto evens = filter(nums, isEven);  // evens = {2,4,6}return 0;
}

四、C++17 Lambda 与之前版本的对比

特性C++11/14 支持度C++17 支持度
constexpr Lambda不支持(需手动包装)自动支持(符合条件时)
按值捕获 *this不支持(仅 [this] 按引用)支持 [*this] 按值捕获副本
显式模板参数不支持(仅 auto 参数)支持 <typename T> 模板参数
作为非类型模板参数不支持支持(需 constexpr
初始化捕获 auto部分支持(需显式类型)完全支持 auto 推导

总结

C++17 显著增强了 Lambda 表达式的功能,使其从“简单匿名函数”升级为支持 编译期计算安全对象捕获复杂泛型逻辑 的强大工具。这些特性尤其在模板编程、异步编程、泛型算法中能大幅简化代码,提升可读性和安全性。掌握 C++17 Lambda 是现代 C++ 开发的重要技能。

http://www.dtcms.com/a/479452.html

相关文章:

  • 四川建设厅网站施工员证查询网站建设找盛誉网络
  • 了解网站开发 后台流程详情页尺寸
  • 2025年10月13日
  • 使用Reindex迁移Elasticsearch集群数据详解(上)
  • 网站设计 优帮云北京做网站公司电话
  • 上海高端网站制作公司专业网站设计建设服务
  • 大模型-CLIP 双编码器架构如何优化图文关联
  • [Qlib] `Model` | `fit` `predict`
  • 线程池Executors
  • 莆田企业网站建设网站建设的会计核算
  • Redis集群架构详解:如何实现高可用和高性能
  • 凤岗网站建设电商系统架构图
  • 知乎 上海做网站的公司自己做一个网站需要多少钱
  • 广州网站开发怎么做如何利用网站来提升企业形象
  • ESD防护设计宝典(八):能量的阀门——电源分配网络(PDN)设计
  • 怎么建设网站规划网站开场动画怎么做
  • 帝国cms怎么做网站地图竞价推广代运营公司
  • C语言--VSCode开发环境配置
  • 企业网站建设智恒网络山东网站营销seo哪家好
  • 12380网站建设打算手机网站建设liedns
  • 为什么做营销型网站网站的经营推广
  • 公章在线制作网站沈阳建设工程质量安全
  • vtkImageThreshold 图像阈值处理指南:从基础到实战优化
  • 佳木斯网站建设公司企业产品展示网站源码
  • MySQL8数据库高级特性
  • 遵义网站建设gzyhg设计一个网站多少钱
  • 设置自己的网站php+mysql网站开发...
  • C++ Builder XE在RzListView1中使用 Selected 属性获取行号,双击显示选中某行的行号
  • 广告制作公司的营业成本沧州网站建设优化案例
  • C语言多次输入过程中getchar()“被跳过”问题