C++11特性(17):lambda函数

7-C++11/14/17 特性整理 + Effective Modern C++ 条款实践(三) 通俗定义MyClass()→ 无参初始化,仅当类无任何用户声明构造时生成;~MyClass()→ 释放资源,含动态内存时需显式定义,C++11默认noexcept;→ 默认浅拷贝,资源类需手动实现深拷贝;→ 默认浅拷贝,需配合深拷贝实现;→ C++11新增,逐成员移动(不可移动则拷贝);→ C++11新增,逐成员移动(不可移动则拷贝);→ 默认返回this,极少主动管控。// 编译器自动生成所有7类特殊成员函数(无显式声明时)MyClass a;// 调用默认构造。 阅读详情
#include <iostream>
#include <vector>
#include <algorithm>     //for_each...
#include <functional>     //plus<int>()...
#include <numeric>     //accumulate...
 
//lambda函数
/*
     lambda函数语法定义:
          [capture](parameters) mutable -> return-type{statement}
     1、[capture]:捕捉列表,
     2、(parameters):参数列表,与普通函数参数列表一致,如果不需要参数列表传递,可以同()一起省略
     3、mutable:mutable修饰符,默认情况下,lambda函数总是一个const表达式,mutable可以取消其常量性,在使用该修饰符时,参数列表不能省略,即使参数为空
     4、->return_type:返回类型,用追踪返回类型形式声明函数的返回类型。若不需要返回值的时候,可以连同符号->一起省略,此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导
     5、{statement}:函数体,与普通函数体一样,除了使用参数之外,还可以使用所有捕获的变量

     捕捉列表的简单形式:
     [var]:表示值传递方式捕捉变量var
     [=]:表示值传递方式捕捉所有父作用域的变量,包括this
     [&var]:表示引用传递捕捉变量var
     [&]:表示引用传递捕捉所有父作用域的变量,包括this
     [this]:表示值传递方式捕捉当前的this指针
 
     复杂的组合形式:注意不允许重复捕捉变量
     [=,&var1,&var2]:表示以引用传递的方式捕捉变量var1和var2,值传递的方式捕捉其他所有变量
     [&,var1,this]:表示以值传递的方式来捕捉变量var1和this,引用传递方式捕捉其他所有变量
     //error
     [=,var1]:这里的=已经以值传递方式捕捉了所有的变量,再捕捉var1变量重复
     [&,&var1]:这里的&已经以引用传递捕捉了所有的变量,再捕捉var1变量重复
*/
 
//仿函数
class _functor
{
public:
     _functor() = default;
     int operator()(int a, int b)
     {
          return (a + b);
     }
};
 
int CommonFun(int times)
{
     //在程序运行时需要修改x的值,所以不能声明为const
     int x = 0;
     try
     {
          for (int i = 0; i < times; ++i)
               x += i;
     }
     catch (...)
     {
          x = 0;
     }
     return x;
}
 
int LambdaFun(int times)
{
     //在lambda函数中,只需使用其函数返回值,所以可以声明为const来保证起常量性
     const int y = [=]
     {
          int val = 0;
          try
          {
               for (int i = 0; i < times; ++i)
                    val += i;
          }
          catch (...)
          {
               val = 0;
          }
          return val;
     }();
     return y;
}
 
void OneCond(int val)
{
     //传统for循环查找是否有val值
     for (auto i = nums.begin(); i != nums.end(); ++i)
     {
          if (*i == val)
               break;
     }
     
     //内置仿函数equal_to
     std::find_if(nums.begin(), nums.end(), std::bind2nd(std::equal_to<int>(), val));
 
    //使用lambda函数
     std::find_if(nums.begin(), nums.end(), [=](const int& i)
     {
          return i == val;
     });
}
 
void Add(const int val)
{
     auto print = [&]
     {
          for (auto n : nums)
               std::cout << n << "\t";
          std::cout << std::endl;
     };
 
    //传统for循环
     for (auto i = nums.begin(); i != nums.end(); ++i)
     {
          *i += val;
     }
     print();
 
     //for_each以及内置仿函数,此处的plus<int>()只是将加法结果返回,而不会再次应用到vector的nums上
     std::for_each(nums.begin(), nums.end(), std::bind2nd(std::plus<int>(), val));
     print();
 
     //对上述的改进,将加法结果再次传送到vector的nums中
     std::transform(nums.begin(), nums.end(), nums.begin(), std::bind2nd(std::plus<int>(), val));
     print();
 
     //lambda函数及for_each
     std::for_each(nums.begin(), nums.end(), [=](int &i)
     {
          i += val;
     });
     print();
}
 
std::vector<int> nums = { 1, 2, 9, 10, 21, 45, 37, 81 };
std::vector<int> LargeNums;
const int ubound = 10;
inline void LargeNumsFun(int i)
{
     if (i > ubound)
          LargeNums.push_back(i);
}
 
class LargeNumsClass
{
public:
     LargeNumsClass(int b) :bound(b){}
     void operator()(int val) const
     {
          if (val > bound)
               LargeNums.push_back(val);
     }
private:
     int bound;
};
 
void Stat(std::vector<int> &iv)
{
     int errors, scores;
     auto print = [&]
     {
          std::cout << "Errors: " << errors << std::endl  << "Score: " << scores << std::endl;
     };
     errors = std::accumulate(iv.begin(), iv.end(), 0);    //add
     scores = std::accumulate(iv.begin(), iv.end(), 100, std::minus<int>());    //minus
     print();
 
     errors = 0;
     scores = 100;
     std::for_each(iv.begin(), iv.end(), [=](const int& i)mutable
     {
          errors += i;
          scores -= i;
     });
     print();
}
 
int main()
{
     int a = 3, b = 4;
     //仿函数
     _functor f;
     std::cout << f(a, b) << std::endl;     //7
 
     //lambda函数
     auto fun = [=]{return a + b; };
     std::cout << fun() << std::endl;     //7
     std::cout << "CommonFun(10) = " << CommonFun(10) << std::endl;     //45
     std::cout << "LambdaFun(10) = " << LambdaFun(10) << std::endl;     //45
     std::cout << "=============================" << std::endl;
     /*
      注意点:
      1、对于按值方式传递的捕捉列表,其传递的值在lambda函数定义的时候就已经决定了
      2、按引用传递的捕捉列表变量,其传递的值则为调用lambda函数时的值。
      总结:
      1、如果需要捕捉的值成为lambda函数的常量,通常使用按值传递的方式捕捉
      2、如果捕捉的值成为lambda函数运行时的变量(类似参数),则应该采用按引用传递的方式捕捉
      */
     int j = 12;
     auto by_val_lambda = [j]{return j + 1; };
     auto by_ref_lambda = [&j]{return j + 1; };
     std::cout << by_val_lambda() << std::endl;     //13
     std::cout << by_ref_lambda() << std::endl;     //13

     j++;
     std::cout << by_val_lambda() << std::endl;     //13
     std::cout << by_ref_lambda() << std::endl;     //14

     std::cout << "=============================" << std::endl;
     //C++11标准中允许lambda表达式向函数指针的转换,但前提是lambda函数没有捕捉任何变量,且函数指针所示的函数原型,必须跟lambda函数有着相同的调用方式
     auto totalChild = [](int x, int y)->int{return x + y; };
     typedef int(*TwoFun)(int, int);
     typedef int(*OneFun)(int);
     TwoFun tf;
     tf = totalChild;     //ok,lambda函数转换为函数指针
 
     OneFun of;
     of = totalChild;     //error,参数不一致

     decltype(totalChild) allChild = totalChild;
     decltype(totalChild) total = tf;     //error,函数指针无法转换为lambda

     std::cout << "=============================" << std::endl;
     //lambda常量性与mutable关键字
     int val = 2;
     auto const_val_lambda = [val]{val = 3; };     //error
     std::cout << "val = " << val << std::endl;     //2

     val = 2;
     auto mutalb_val_lambda = [val]()mutable{val = 3; };
     mutalb_val_lambda();
     std::cout << "val = " << val << std::endl;     //2

     val = 2;
     auto const_ref_lambda = [&val]{val = 3; };
     const_ref_lambda();
     std::cout << "val = " << val << std::endl;     //3

     val = 2;
     auto const_param_lambda = [&val](int v){v = 3; };
     const_param_lambda(val);
     std::cout << "val = " << val << std::endl;     //2

     std::cout << "=================================" << std::endl;
     //传统for循环
     LargeNums.clear();
     for (auto iter = nums.begin(); iter != nums.end(); ++iter)
     {
          if (*iter > ubound)
               LargeNums.push_back(*iter);
     }

     //使用函数指针
     LargeNums.clear();
     std::for_each(nums.begin(), nums.end(), LargeNumsFun);
    
     //使用仿函数
     LargeNums.clear();
     std::for_each(nums.begin(), nums.end(), LargeNumsClass(ubound));

     //使用lambda函数
     LargeNums.clear();
     std::for_each(nums.begin(), nums.end(), [=](const int& val)
     {
          if (val > ubound)
               LargeNums.push_back(val);
     });

     std::cout << "===========================" << std::endl;
     std::vector<int> iv(10);
     std::generate(iv.begin(), iv.end(), []{return rand() % 10; });
     Stat(iv);
 
     return 0;
}

====================打个广告,欢迎关注====================

QQ:412425870
csdn博客:
http://blog.youkuaiyun.com/caychen
码云:
https://gitee.com/caychen/
github:
https://github.com/caychen

点击群号或者扫描二维码即可加入QQ群:

328243383(1群)



点击群号或者扫描二维码即可加入QQ群:

180479701(2群)



C++ 11,14,17中的 Lambda 表达式 _ Microsoft Docs[2].pdf 查Lambda表达式资料时很容易被函数闭包、Lambda演算、形式系统这些深奥名词淹没而放弃学习,其实Lambda表达式就是匿名函数(annoymous function)——允许我们使用一个函数,但不需要给这个函数起名字。还是有点难懂?没关系,看完此资料就清楚了。 c++11,14,17新增Lambda详解 立即下载

相关推荐

无线图像传输新突破:深度JSCC算法在低带宽环境下的性能实测

本文深入探讨了基于深度学习的信源信道联合编码(JSCC)算法在低带宽无线图像传输中的突破性表现。通过实测数据对比,深度JSCC在低信噪比环境下展现出卓越的鲁棒性,有效对抗传统方案的“悬崖效应”,实现图像质量的平滑下降,为远程医疗、工业巡检等严苛场景提供了新的解决方案。

weixin_29090089的博客 504

C++中的Lambda表达式

一个lambda表达式表示一个可调用的代码单元,可理解为一个未命名的内联函数。一个lambda表达式具有一个返回类型、一个参数列表和一个函数体 [capture list ] ( ...

Appleeatingboy的博客 3820

具身智能端到端大模型VLA (Vision Language Action)

在语言为条件的机器人任务中,策略必须具备理解语言指令、视觉感知环境并生成适当动作的能力,这就需要VLA的。例如,在自动驾驶领域,传统的做法是将感知、预测、规划等步骤分开处理,而VLA则试图用一个统一的框架来替代这种分立的方法。另外,VLA的模型对于算力的需求很大,单片AI算力1000Tops的Thor大概率会延期发布,加上英伟达芯片的量产时间与成本挑战,以及在国内的应用情况,对车企而言是个大问题。以谷歌DeepMind推出的RT-2为例,该模型可以在新的物体、背景和环境中表现出显著改善的性能。

具身智能机器人 1万+

C++17中lambda表达式新增加支持的features

C++17中lambda表达式新增加支持的features

网络资源是无限的 1385

PyCharm 2023最新版安装配置全攻略(附永久激活教程)

本文详细介绍了PyCharm 2023最新版的安装配置全流程,包括版本选择、初始配置、插件生态、工程模板、调试优化及团队协作等关键步骤。特别针对专业版和社区版的功能差异进行对比,帮助开发者高效搭建Python开发环境,提升编码效率与团队协作能力。

p4q5r6s7t的博客 864

【Java】对接微信转账到零钱接口 Java微信商家转账 apiV3(该踩的雷都踩了)

配置apiv3依赖java代码。

Moonhwa的博客 4316

C++17之lambda扩展

c++ 11引入的Lambdas和用c++ 14引入的generic Lambdas都是成功的例子。lambda的使用使得我们在一些地方比函数方便很多。 c++ 17改进了lambda的功能,允许在更多的地方使用lambdas: 在constant表达式(即,在编译时期); 在需要当前对象副本的地方(例如,在线程中调用lambdas时)。 1.constexpr ...

janeqi1987的专栏 2369

Apollo&Carla联合仿真环境搭建与实战调试

本文详细介绍了Apollo与Carla联合仿真环境的搭建与实战调试流程,涵盖硬件配置、软件依赖安装、Apollo环境配置、Carla仿真器安装、桥接服务设置以及常见问题解决方案。通过逐步指导,帮助开发者高效实现自动驾驶仿真测试,提升开发效率。

ee345的博客 200

[新特性] C++17 Lambda函数

返回类型(auto)之后、等号之前的,是函数名(func);圆括号内是外参(param)。那多出来的方括号有什么用?里面填什么?🤔// 关键字mutable意义:// 有,则函数体 function body 内 捕获变量capture caluse 可变;// 无,则函数体 function body 内 捕获变量caputure caluse 常量方括号捕捉到的变量[capture clause],看上去似乎和圆括号的外参(parameters)没什么区别。但是方括号内是已赋值的。

当家的博客 569

RT-DETR-R18 的轻量化 Trick:剪枝与量化在模型中的应用

RT-DETR-R18轻量化技术通过结构化剪枝、混合精度量化和知识蒸馏的组合优化,实现了显著模型压缩效果。摘要如下: RT-DETR-R18模型通过创新轻量化技术组合,在保持46.2% mAP精度的前提下,将模型大小压缩至2.1MB(压缩率78%),计算量降至3.2 GFLOPs(减少78.2%),实现移动端28ms实时推理(加速37.8%)。核心技术包括:1)渐进式结构化剪枝系统,通过L1范数重要性评估和动态剪枝调度;2)混合精度量化策略,对关键层保留FP16精度;3)教师-学生知识蒸馏框架保持模型表达能

走向CTO的路上... 1188

C#【通用方法】字节数组添加、移除、获取的方法类(妙用List<byte>,开发中常用)

C#【通用方法】添加移除字节的方法类(妙用List,开发中常用)

星Yeah 的博客 3357

C++ ——必知必会之C++ 17 新特性汇总片段

C++ 17 新特性小结。

最美不过,心中有梦,身旁有你! 2417

USB驱动(URB)

本文介绍了Linux内核中USB驱动开发的核心概念URB(USB Request Block)。URB是主机与USB设备间传输数据的抽象结构体,包含目标设备、端点信息、数据缓冲区等关键字段。文章详细解析了URB的生命周期(分配、填充、提交、回调、释放)、四种传输类型(控制、批量、中断、等时)及其应用场景,并提供了鼠标设备的中断传输示例代码。最后强调了URB使用注意事项,包括DMA缓冲区分配、错误处理和资源释放等。URB作为USB驱动与内核通信的桥梁,是构建稳定USB驱动程序的基础。

m0_49476241的博客 915

C++11 Lambda表达式:语法、使用场景和扩展

C++11 中的 Lambda 表达式,语法、捕获方式、使用场景,在 C++ 后续标准中的扩展、优点,注意事项。

有耐心做好简单事情,坚持写blog 998

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

有关C ++中Lambda函数的所有信息:从C ++ 11到C ++ 17

Lambda函数是C ++ 11中引入的Modern C ++的直观概念,因此在Internet上有关lambda函数教程的文章已经很多。 但是,仍然有一些难以言喻的东西(例如IIFE,lambda类型等),没人谈论。 因此,在这里,我不仅要向您展示C ++中的lambda函数,而且还将介绍Lambda在内部的工作方式以及Lambda的其他方面。 /!\:最初发布于@ www.vishalch...

编程故事的地方 271

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

C++ 11-14-17-20 新特性变化

扩展用法,可用于定义内联变量,功能与内联函数相似。inline可避免函数或变量多重定义的问题,如果已定义相同的函数或变量(且该函数或变量声明为inline),编译器会自动链接到该函数或变量。

lovely_yoshino的博客 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

c++11,14,c++17新特性

智能指针:引入了shared_ptr、unique_ptr和weak_ptr等智能指针,用于管理动态分配的内存,避免内存泄漏和悬挂指针问题。C++11、C++14和C++17是C++语言的三个重要版本,它们引入了许多新的特性和改进。if constexpr语句:允许在编译时根据条件选择不同的代码路径,从而提高了代码的灵活性和性能。线程支持库:引入了std::thread和std::mutex等类,提供了对多线程编程的支持。结构化绑定:允许将元组或结构体的成员绑定到单独的变量中,提高了代码的可读性和简洁性。

m0_69644480的博客 509

C++ 11/14/17/20新特性

C++从11到20经历了四次重大更新,每次更新都显著提升了语言的表达能力、性能和安全性。C++11是C++历史上最具革命性的更新之一,引入了大量基础特性,彻底改变了C++的编程风格。

u010632343的博客 1万+

C++学习:C++11扩展:constexpr特性

之前我们已经学习了C++11的一些特性。那些十分重要。C++11对于C++整个的发展也是转折性的,受限于篇幅限制我们并没有完全讲完,本期我们就来学习C++11的其他特性。

2401_89119815的博客 1171

c++11新特性

/ 将 std::vector<std::vector<int>> 定义为 IntMatrix 类型的别名。// 将 std::list<std::string> 定义为 StringList 类型的别名。// 将 std::vector<int> 定义为 IntVector 类型的别名。// 将 std::vector<int> 定义为 IntVector 类型的别名。// 使用列表初始化初始化一个向量。

lpt111111111的专栏 445

c++ 之 lambda表达式

Lambda 表达式是 C++11 引入的一项重要特性,它允许在代码中定义匿名函数对象(闭包)。Lambda 提供了一种简洁的方式来创建临时的、一次性的函数对象。

qq_31266667的博客 1808

C++11/14/17新特性解析

从C++11的constexpr函数到C++14的放松限制,再到C++17的if constexpr编译期条件判断,编译期计算能力持续增强。模板元编程与constexpr结合创造了新的编程范式,使程序在保持高性能的同时具备更强的表现力。类型推导体系的完善使C++在保持静态类型安全的同时,减少了冗余类型声明。variant和optional等类型安全容器的引入,减少了未定义行为的发生概率,提高了代码的健壮性。内联变量、改进的模板特性都为模块化编程打下基础,解决了头文件包含带来的编译延迟和依赖问题。

weixin_42383071的博客 896

C++面试知识点总结

C++面试知识点总结

bigger_belief的博客 4748

C++ Lambda 表达式详解

1. 基本语法cpp复制下载[capture]:捕获列表,指定如何捕获外部变量:参数列表(可省略)mutable:允许修改按值捕获的变量(可省略):返回类型(可自动推导时可省略){ body }:函数体2. 捕获列表详解捕获方式效果[]不捕获任何外部变量[=]按值捕获所有外部变量(默认const,不可修改)[&]按引用捕获所有外部变量[x]仅按值捕获x[&x]仅按引用捕获x[=, &x]默认按值捕获,但x按引用捕获[&, x]默认按引用捕获,但x按值捕获[this]捕获当前类的this指针。

2301_81882590的博客 930

C++特性小总结

这里主要是介绍一下C++的新特性,包括C++11、C++14、C++17等 C++的特性 构造和析构 常用的关键字 static 首先是熟悉的面向过程: static在面向对象过程中的使用 virtual关键字 register关键字关键字 extern关键字 explicit 深拷贝浅拷贝 多态 四种类型转换 static_cast: const_cast dynamic_c

二货磁铁 2141

C++ Lambda表达式默认参数详解:从C++11到C++20的演进与实战

在C++编程中,函数默认参数是一种常见的语法糖,它允许在调用函数时省略部分参数,编译器会自动使用预定义的默认值。这一机制简化了函数调用,提升了代码的复用性和可读性。其原理是在编译阶段,编译器将函数调用处缺失的参数替换为指定的默认值。从技术价值看,默认参数减少了函数重载的数量,使接口设计更加简洁。在泛型编程和API设计中,它常用于配置选项、设置默认行为等场景。然而,当这一基础概念与C++11引入的Lambda表达式结合时,却产生了独特的限制与演进。C++11/14/17标准明确禁止在Lambda参数列表中直接

weixin_30846347的博客 321
上一篇: C++11特性(16):默认函数控制
下一篇: C++11特性(18):对齐方式
caychen
博客等级 码龄9年 110粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值