【c++学习】c++11的特性(2)

本文介绍了C++11中的可变参数模板,展示了如何使用sizeof...获取参数包数量,以及lambda表达式的基础语法、捕获子句和包装器(如function()和bind函数)的应用。
摘要由CSDN通过智能技术生成

可变参数模板

C++11 引入了可变参数模板(variadic templates),这是一个非常强大的特性,它允许你定义模板函数或模板类,这些模板可以接受任意数量和类型的参数。可变参数模板常用于实现元编程(metaprogramming)和通用编程(generic programming)。

// Args是一个模板参数包,args是一个函数形参参数包
// 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。
template <class ...Args>
void ShowList(Args... args)
{}

sizeof…

这个函数主要是用来获取(args…)参数包中的数量。

void showlist(Args... args)
{
	//_showlist(args...);
	cout << sizeof...(args) << endl;
}
int main()
{
	showlist(1);
	showlist(1,2);
	showlist(1, 2,'x');

}

如下图:
在这里插入图片描述

打印可变参数包

void _showlist()
{
	cout << endl;
}
template<class T, class ...Args>
void _showlist(T& t, Args... args)
{
	cout << t << " ";
	_showlist(args...);
}
template<class ...Args>
void showlist(Args... args)
{
	_showlist(args...);
}
int main()
{
	showlist(1);
	showlist(1,2);
	showlist(1, 2,'x');

}

用于编译时展开参数包,_showlist函数的T& t参数用于每次递归时,都从args…中获取首元素,直到args…参数包为空时,则去递归特定的_showlist()函数来结束递归!
在这里插入图片描述

lambda表达式

C++11 引入了 lambda 表达式,它是一种简洁的、匿名的函数对象,可以用于定义小的、内联的函数对象。Lambda 表达式在函数式编程中非常常见,但在 C++11 之前,C++ 标准库并没有直接支持这种特性。Lambda 表达式的引入使得 C++ 在表达式编程方面更加强大和灵活。

基本语法

[capture](parameters) -> return_type { body_of_lambda }

capture:捕获子句,用于捕获外部作用域的变量,可以有不同的捕获模式。
parameters:参数列表,与普通函数的参数列表相似。
return_type:返回类型,可以省略,编译器会自动推导。
body_of_lambda:lambda 函数的主体,包含一系列语句。

捕获子句

[]:不捕获任何外部变量。
[=]:以值捕获所有外部变量(只读)。
[&]:以引用捕获所有外部变量。
[a, &b]:以值捕获 a,以引用捕获 b。

代码示例

1、简单的lambda表达式:

int main()
{
	auto f1 = [](int x)->void {cout << x << endl; };//lambda表达式。
	f1(2);
	return 0;
}

在这里插入图片描述

**2、使用捕获子句的 lambda 表达式 **

	int x = 10;
	auto printx = [&] {cout << x << endl; };
	printx();
	return 0;

在这里插入图片描述
**3、修改捕获的变量(使用引用捕获) **

	int x = 10;
	auto revisex = [&] { ++x; };
	revisex();
	cout << x << endl;   
	return 0;

在这里插入图片描述
4、在算法中使用 lambda 表达式

	vector<int> v = { 3,4,2,1 };
	sort(v.begin(), v.end(), [](int& f1, int& f2)->bool {return f1 < f2; });
	for (auto& e : v)
	{
		cout << e << endl;
	}
	return 0;

在这里插入图片描述

包装器

function()包装器

可调用对象:
函数指针,仿函数,lambda表达式。

void swapfunc(int& r1,int& r2)
{
	int tmp = r1;
	r1 = r2;
	r2 = tmp;
}
struct swapc
{
	void operator()(int& r1, int& r2)
	{
		int tmp = r1;
		r1 = r2;
		r2 = tmp;
	}
};
int main()
{
	int x = 0, y = 1;
	auto swaplambda = [](int& r1, int& r2)
		{
			int tmp = r1;
			r1 = r2;
			r2 = tmp;
		};
	function<void(int&,int&)> f1 = swaplambda;//包装lambda表达式
	f1(x, y);
	cout << x << ":" << y << endl;
	function<void(int&, int&)> f2 = swapfunc;//包装函数指针
	f2(x, y); 
	cout << x << ":" << y << endl;
	function<void(int&, int&)> f3 = swapc();//包装仿函数
	f3(x, y);
	cout << x << ":" << y << endl;

	return 0;
}

在这里插入图片描述

bind函数

std::bind 是 C++11 标准库中的一个函数模板,它用于生成一个新的可调用对象,该对象会将给定的参数绑定到给定的函数、成员函数或可调用对象的相应参数上。使用 std::bind 可以将普通函数、成员函数或可调用对象转换为具有不同签名的新可调用对象。

改变参数位置。

int sub(int a, int b)
{
	return a - b;
}
int main()
{
	function<int(int, int)> f1 = sub;
	cout << f1(10, 2) << endl;
	function<int(int, int)> f1 = bind(sub, placeholders::_2, placeholders::_1);
	cout << f1(10, 2) << endl;
	return 0;
}

在这里插入图片描述
上图中可以看到,对于参数的传值都是一样的,但是对应的结果却不一样,是因为f2经过bind绑定函数并对其内部的参数进行顺序调整。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值