1、简介
C++提供了两种模板机制,函数模板和类模板。
使用范围:模板的声明或定义只能在全局或类范围进行,不能在局部范围(如函数)内进行。
使用目的:使用模板是为了能够让程序员编写与类型无关的代码。
函数模板和模板函数区别:函数模板是一个模板,其中用到通用类型参数,不能直接执行;模板函数是一个具体的函数,它是一个具体执行的函数,由编译系统在遇到具体函数调用时生成,可执行。
1、函数模板格式
template <类型形参表或称模板参数列表> //类型函数声明
返回类型 函数名(形参表)
{
函数体;
}
注意:
模板参数表:定义在类或函数定义中用到的类型或值。
类型形参表:可以包含基本数据类型,也可以包含类类型。类型形参需要加class或typename关键字(两者等价)
类型形参表的参数必需是唯一的,不能有重名的。
template声明语句和函数模板声明之间不允许有其他语句。
2、函数模板实例化为模板函数
函数模板不能直接执行需要实例化为模板函数后才能执行。
编译系统发现有一个函数调用“函数名(实参表)”或“函数名<类型实参表>(实参表)”时,c++将根据“实参表”中的类型生成一个重载函数,即模板函数。
举例:
函数模板:
template
//调用函数模板生成模板函数
cout << abs(-1) << endl;//输出结果为1
生成的模板函数如下:
int abs(int x)
{
if(x<0) return -x;
return x;
}
3、函数模板本身可以重载
1、简介
类模板允许用户为类定义一种模式,使得类中的某些数据成员、成员函数的参数或成员函数的返回值能取任意类型。类模板的成员函数被认为是函数模板。
2、定义类模板格式
template <类型形参表> //类型参数声明
class 类名
{
类模板的代码
}
template<类型形参表> //定义在类模板之外的函数必需以关键字template开始
返回类型 类名 类型名表::成员函数n(形参表)
{
成员函数定义体
}
3、实例化类模板
类模板不能直接使用,必需先实例化为相应的模板类。定义类模板之后,创建模板类的格式如下:
类模板名 <类型实参表> 对象表;
类型实参表与类模板中的类型形参表相匹配。
4、类模板举例
#include
#include
5、类模板作为函数参数
//类模板
template //T 的名字也为其他
class A
{
T x;
public:
A(T a) { x = a; }
T abs()
{
if (x < 0) return -x;
else return x;
}
};
//函数模板中模板类作为形参
template
void fun(A x)
{
cout << x.abs() << endl;
}
int main()
{
//建立对象
A s1(-5);
A s2(-5.8);
fun(s1);
fun(s2);
}
5、类模板中也可以使用非类型参数,即值参数
template
class A
{
.....
}
实例化:
A
6、模板与静态函数
类模板中定义静态函数,则该模板类的所有对象共享一个静态数据成员。
7、类模板的友元函数
一个类模板中可以设计友元函数,友元函数的形参可以是类模板或类模板的引用。如果在类模板中设计与参数类型无关的友元函数,那么在类外面实现时也不能省略template类型参数声明,否则将其看成是一个普通全局函数。
template //T 的名字也为其他
class A
{
public:
T x;
A() { }
A(T i):x(i){ }
friend void f1();//与参数类型无关的友元函数
friend void f2(A &);//与参数类型有关的友元函数
};
template
void f1(){ cout << "f1" << endl; }
template
void f2(A &a) { cout << "f2:x " << a.x << endl; }
int main()
{
A a(1.2);
f1();//f1是模板类A的友元函数
f1();//f1是模板类A的友元函数
f2(a);//f2是模板类A的友元函数
}
1、概况
c++ 11 可变参数模板,对参数进行了高度泛化,能表示任意个数,任意类型的参数。
c++11 可变参数模板,就是一个接受可变数目参数的模板函数或模板类。可变数目的参数被称为参数包。
存在两种 参数包:
模板参数包:表示0个或多个模板参数
函数参数包:表示0个或多个函数参数
2、格式
template
template
举例:
#include
#include
3、统计可变数目参数的个数
#include
using namespace std;
template
void f(T... args)
{
cout << sizeof...(args) << endl;
};
int main()
{
f();
f(1, 2);
f(1, 2.5, "");
}