模板
模板是 C++ 支持参数化多态的工具。
模板是一种对类型进行参数化的工具:通常有两种形式:函数模板和类模板。
函数模板:针对仅参数类型不同的函数。
template <class 形参名,class 形参名,......>
返回类型 函数名(参数列表)
{
函数体
}
在这里 class 等同于 typename.
模板形参需要调用该模板函数时提供的模板实参来初始化模板形参,一旦编译器确定了实际的模板实参类型就称他实例化了函数模板的一个实例。
template <class T> void swap(T& a, T& b){}----->调用 swap(a,b)----> a,b为int时 模板函数被替换为swap(int &a, int &b).
不能在模板函数调用的参数中指定模板形参的类型,比如 swap(int,int).
对函数模板的调用应使用实参推演来进行。
int a, b;
swap(a,b)。
类模板:针对仅数据成员和成员函数类型不同的类。
template<class 形参名,class 形参名,…>
class 类名{ ... };
在类模板外部定义成员函数的方法:
template<模板形参列表> 函数返回类型 类名<模板形参名>::函数名(参数列表){函数体}
对于类模板,模板形参的类型必须在类名后的尖括号中明确指定。
和函数模板一样,模板形参不能为空。
当在类外面定义类的成员时template 后面的模板形参应与要定义的类的模板形参一致。
模板的声明或定义只能在全局,命名空间或类范围内进行。
即不能在局部范围,函数内进行,比如不能在 main 函数中声明或定义一个模板。
lambda
![](https://i-blog.csdnimg.cn/blog_migrate/a3a66424b7933cfc220eda6c5f063dc4.png)
1.捕获列表。在C++规范中也称为Lambda导入器, 捕获列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数,捕获列表能够捕捉上下文中的变量以供Lambda函数使用。
2.参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略。
3.可变规格。mutable修饰符, 默认情况下Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
4.异常说明。用于Lamdba表达式内部函数抛出异常。
5.返回类型。 追踪返回类型形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
6.lambda函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
[],空捕获列表,不捕获任何变量,此时引用外部变量则会提示编译错误。
[=],默认按值捕获全部变量。
[&],默认按引用捕获全部变量。
[=,&x,&y],默认按值捕获全部变量,但是变量x,变量y按引用捕获。
[&,=x,=y],默认按引用捕获全部变量,但是变量x,变量y按值捕获。
[&,x,y],效果同上,即变量名前面没有写=或者&时,默认为按值捕获。
[=,x,y],编译出错,变量x,变量y按值捕获,和默认按值捕获全部变量重复。
[x,y],只按值捕获变量x和变量y。
[&x,&y],只按引用捕获变量x和变量y。
[x,&y],只按值捕获变量x,按引用捕获变量y。
[=x,=y],编译出错,应为[x,y]。
[this],捕获this指针,然后在Lambda表达式内部就可以直接引用类成员了。