可变参数模板
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绑定函数并对其内部的参数进行顺序调整。