【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关键字
相关推荐
寻寻觅觅☆8 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
fpcc8 小时前
并行编程实战——CUDA编程的Parallel Task类型
c++·cuda
l1t8 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
赶路人儿9 小时前
Jsoniter(java版本)使用介绍
java·开发语言
ceclar1239 小时前
C++使用format
开发语言·c++·算法
码说AI10 小时前
python快速绘制走势图对比曲线
开发语言·python
Gofarlic_OMS10 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
lanhuazui1010 小时前
C++ 中什么时候用::(作用域解析运算符)
c++
charlee4410 小时前
从零实现一个生产级 RAG 语义搜索系统:C++ + ONNX + FAISS 实战
c++·faiss·onnx·rag·语义搜索
星空下的月光影子10 小时前
易语言开发从入门到精通:补充篇·网络爬虫与自动化采集分析系统深度实战·HTTP/HTTPS请求·HTML/JSON解析·反爬策略·电商价格监控·新闻资讯采集
开发语言