首页 > 编程语言 >C++ lambda

C++ lambda

时间:2024-08-27 12:57:20浏览次数:9  
标签:变量 int C++ 列表 捕捉 lambda 函数

文章目录

C++的lambda表达式是C++11及以后版本中引入的一种强大的特性,它提供了一种简洁的方式来定义匿名函数对象。Lambda表达式能够捕获其所在作用域中的变量(以值或引用的方式),并允许你在需要函数对象的地方(比如算法库中的函数对象参数)以非常简洁的方式定义和使用这些函数。

基本语法

[capture-list](parameters) mutable -> return_type {  
    // 函数体  
}

[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。

(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略

mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。

->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。

函数体:在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。

注意:
在lambda函数定义中,参数列表和返回值类型都是可选部分,而捕捉列表和函数体可以为空。因此C++11中最简单的lambda函数为:[]{}; 该lambda函数不能做任何事情

示例:

简单的lambda表达式

#include <iostream>  
#include <vector>  
#include <algorithm>  
  
int main() {  
    std::vector<int> v = {1, 2, 3, 4, 5};  
  
    // 使用lambda表达式来打印每个元素  
    std::for_each(v.begin(), v.end(), [](int x) { std::cout << x << " "; });  
  
    return 0;  
}

在这里插入图片描述

捕捉列表

捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式传值还是传引用。

[var]:表示值传递方式捕捉变量var
[=]:表示值传递方式捕获所有父作用域中的变量(包括this)
[&var]:表示引用传递捕捉变量var
[&]:表示引用传递捕捉所有父作用域中的变量(包括this)
[this]:表示值传递方式捕捉当前的this指针

注意:
a. 父作用域指包含lambda函数的语句块
b. 语法上捕捉列表可由多个捕捉项组成,并以逗号分割
比如:[=, &a, &b]:以引用传递的方式捕捉变量a和b,值传 递方式捕捉其他所有变量
[&,a, this]:值传递方式捕捉变量a和this,引用方式捕捉其他变量
c. 捕捉列表不允许变量重复传递,否则就会导致编译错误。
比如:[=, a]:=已经以值传递方式捕捉了所有变量,捕捉a重复
d. 在块作用域以外的lambda函数捕捉列表必须为空。
e. 在块作用域中的lambda函数仅能捕捉父作用域中局部变量,捕捉任何非此作用域或者
非局部变量都
会导致编译报错。
f. lambda表达式之间不能相互赋值,即使看起来类型相同

示例:

捕获外部变量:

#include <iostream>  
#include <vector>  
#include <algorithm>  

int main() {
    int sum = 0;
    int multiplier = 2;
    std::vector<int> v = { 1, 2, 3, 4, 5 };

    // 捕获外部变量sum(按引用)和multiplier(按值)  
    std::for_each(v.begin(), v.end(), [&sum, multiplier](int x) {
        sum += x * multiplier;
        });

    std::cout << "Sum: " << sum << std::endl; // 输出: Sum: 30  

    return 0;
}

在这里插入图片描述

修改捕获的变量

#include <iostream>  

int main() {
    int x = 10;

    // 使用mutable关键字来修改捕获的变量  
    auto lambda = [x]() mutable { x = 20; };
    lambda();

    std::cout << "x: " << x << std::endl; // 注意:这里输出的是10,因为lambda捕获的是x的副本  

    // 捕获引用  
    [&x]() { x = 30; }();
    std::cout << "x: " << x << std::endl; // 输出: x: 30  

    return 0;
}

在这里插入图片描述

函数对象与lambda表达式

函数对象,又称为仿函数,即可以像函数一样使用的对象,就是在类中重载了operator()运算符的类对象。

class Rate
{
public:
	Rate(double rate) : _rate(rate)
	{}
	double operator()(double money, int year)
	{
		return money * _rate * year;
	}
private:
	double _rate;
};
int main()
{
	// 函数对象
	double rate = 0.49;
	Rate r1(rate);
	r1(10000, 2);
	// lamber
	auto r2 = [=](double monty, int year)->double {return monty * rate * year;
		};
	r2(10000, 2);
	return 0;
}

从使用方式上来看,函数对象与lambda表达式完全一样。
函数对象将rate作为其成员变量,在定义对象时给出初始值即可,lambda表达式通过捕获列表可以直接将该变量捕获到。
在这里插入图片描述
实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,即:如果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()。

标签:变量,int,C++,列表,捕捉,lambda,函数
From: https://blog.csdn.net/2301_79274600/article/details/141599803

相关文章

  • C++常见内存错误及其对策
    常见内存错误及其对策目录常见内存错误及其对策内存分配未成功,却使用了它内存分配成功但未初始化内存操作越界内存泄漏释放内存后继续使用规则总结图表示C++学习资料在软件开发过程中,内存管理是至关重要的一环。内存错误不仅会导致程序崩溃,还可能引发安全问题。本文......
  • c++教程之三大结构
    C++顺序结构教程在编程的世界里,顺序结构是构建所有程序的基础。无论是简单的脚本还是复杂的应用程序,它们都是由一系列按照特定顺序执行的指令组成的。C++,作为一种高效、灵活的编程语言,同样遵循这一原则。本教程将深入介绍C++中的顺序结构,包括变量与数据类型、运算符与表达式、......
  • C++笔记9•list•
    容器之list1.list的介绍(1).list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。(2).list的底层是双向循环链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。(3).优......
  • C++学习 — 函数
    目录1.概述2.函数的定义3.函数的调用4.值传参5.函数的常见样式6.函数的声明7.函数的分文件编写8.函数默认参数 9.函数占位参数10.函数重载(1)函数重载概述(2)函数重载注意事项1.概述作用:将一段经常使用的代码封装起来,减少重复代码   一个较大的程序,一般......
  • 202009-1 称检测点查询 csp c++组
    a数组记录距离平方值,其最大为2000的平方,不超int。b数组记录3个距离最小的坐标。ans记录下标。每次选出一个坐标后其距离置为最大值。include<bits/stdc++.h>typedeflonglongll;usingnamespacestd;intmain(){intn,x,y,x1,y1,j,minx,b[3],cnt=0,i,ans;inta[210......
  • C/C++开发神器CLion全新发布v2024.2——更适用于嵌入式开发
    CLion是一款专为开发C及C++所设计的跨平台IDE。它是以IntelliJ为基础设计的,包含了许多智能功能来提高开发人员的生产力。这种强大的IDE帮助开发人员在Linux、OSX和Windows上来开发C/C++,同时它还使用智能编辑器来提高代码质量、自动代码重构并且深度整合CMake编译系统,从而提高......
  • C++码表之Unicode
    今日诗词:折花逢驿使,寄与陇头人。江南无所有,聊赠一枝春。                     ——《赠范晔诗》【南北朝】陆凯引言:上一期我们说到了ASCII码表,这是一种现如今不是那么通用的机制,随着计算机的普及,越来越多的人开始学习计算机,深......
  • C++容器之字符串的详解
    每日诗词:我见青山我妩媚,料青山见我应如是。                             ——《贺新郎·甚矣吾衰矣》【宋】辛弃疾目录补漏:vector在分配新内存块后如何进行元素复制正文:字符串变量和常量字符串变量:解析:......
  • 学习C++的阶段总结
    每日诗词:盛气光引炉烟,素草寒生玉佩。应是天仙狂醉,乱把白云揉碎。                        ——《清平乐·画堂晨起》【唐】李白目录月末学习总结展望和感谢通知我的目标是:共同进步下期预告:搞定C++指针;更新时间:待定......
  • LeetCode 算法:爬楼梯 c++
    原题链接......