【C++11】lambda和可变参数模板

为了解决冗杂的函数指针(void (*p)(int a)),仿函数(通过类内重载operator())。C++11定义了lambda表达式,作为一个匿名函数对象,它可以直接再函数内部直接定义使用。以及如何像printf一样一直传入参数的问题

一.lambda表达式

书写格式

【capture-list】(parameters)mutable-> return-type {statement}

  • capture-list:捕捉列表,捕捉上下文中的变量供lambda函数使用

    • 【var】:表示值传递捕捉变量var(const变量不可修改)
    • 【=】:表示值传递方式捕捉所有父作用域中的变量(含this)
    • 【&var】:表示引用传递捕捉变量var
    • 【&】:表示引用传递捕捉所有父作用域的变量(含this)
  • parameters:参数列表,一致于普通函数的参数列表,若不需参数传递,可以省略()

  • mutable:默认情况下,lambda函数是const函数,使用该关键字取消常量性

  • ->returntype:返回值类型明确情况下,可以省略,由编译器对返回类型推导

  • {statement}:函数体

注意:语法上捕捉列表可由多个捕捉项构成,以逗号分隔。如【&a, &b】,【&,this】(this通过传值方式捕捉)。捕捉列表不允许变量重复传递,lambda表达式之间不能相互赋值

情景1:

情景2:传值捕捉,局部域的修改不影响域外的a, b。栈帧销毁

情景3:使用mutable取消常量性

小结:lambda底层是仿函数,编译器生成仿函数的类,传值传参就是在给仿函数传递,又通过调用构造函数和operator()完成任务。使用UUID作为lambda唯一标识码


可变参数模板

怎么像printf一样一直传入参数?

可变参数模板:创建接收可变参数的函数模板和类模板

  • 我们可以观察到,要使用这个模板需要将参数包扩展
  • 解参数包1

数组初始化时会推断应该开多大的数组,这时会把扩展包展开,调用函数

  • 解参数包2

使用场景

cpp 复制代码
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date构造" << endl;
	}

	Date(const Date& d)
		:_year(d._year)
		, _month(d._month)
		, _day(d._day)
	{
		cout << "Date拷贝构造" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};
template<class ...Args>
Date* Creat(Args ...args)
{
	Date* ret = new Date(args...);
	return ret;
}
int main()
{
	Date* p1 = Creat();
	Date* p2 = Creat(2023);
	Date* p3 = Creat(2023, 9);
	Date* p4 = Creat(2023, 9, 27);

	Date d(2023, 1, 1);
	Date* p5 = Creat(d);
}

emplace_back模板的可变参数+万能引用

  • 使用场景

emplace_back通过参数包使用直接构造,push_back使用构造函数出对象来,再作为将亡值,调用移动构造。对于移动构造的消耗不是很大,于是两种方法效率差不多

  • 使用情景

移动构造函数&&移动赋值重载

  • 如果没有实现移动构造函数,没有实现析构函数,拷贝构造函数,拷贝赋值重载中的任意一个。编译器会自动生成一个默认移动构造,对于内置类型成员(逐字节拷贝)。对于自定义类型成员,如果类内没有实现移动构造,就调用拷贝构造,否则调用调用移动构造函数
  • 移动赋值重载同理
  • 一般浅拷贝的类不需要自己实现上面两个函数,深拷贝的类需要自己实现

default

  • 当实现了析构函数等时,为了使用编译器默认的移动构造,需要使用default关键字
相关推荐
2401_873479406 小时前
如何利用IP查询定位识别电商刷单?4个关键指标+工具配置方案
开发语言·tcp/ip·php
我爱cope7 小时前
【从0开始学设计模式-10| 装饰模式】
java·开发语言·设计模式
菜鸟学Python7 小时前
Python生态在悄悄改变:FastAPI全面反超,Django和Flask还行吗?
开发语言·python·django·flask·fastapi
浪浪小洋8 小时前
c++ qt课设定制
开发语言·c++
charlie1145141918 小时前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
handler018 小时前
Linux: 基本指令知识点(2)
linux·服务器·c语言·c++·笔记·学习
故事和你918 小时前
洛谷-数据结构1-4-图的基本应用1
开发语言·数据结构·算法·深度优先·动态规划·图论
程序猿编码9 小时前
给你的网络流量穿件“隐形衣“:手把手教你用对称加密打造透明安全隧道
linux·开发语言·网络·安全·linux内核
aq55356009 小时前
编程语言三巨头:汇编、C++与PHP大比拼
java·开发语言
aq553560010 小时前
PHP vs Python:30秒看懂核心区别
开发语言·python·php