什么是模板:
模板是c++中泛型编程的基础,一个模板就是一个创建类或函数的蓝图或者说是公式,当使用一个vector这样的泛型类型或者find这样的泛型函数时,我们提供足够的信息,将蓝图转换为特定的类或者函数
函数模板:
定义模板:
假如我们要比较两个数的大小,我们可能会写出下面这样的函数
//比较两个string类参数大小
int compare(const string &v1, const string &v2)
{
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
//比较两个double类型参数
int compare(const double &v1, const double &v2)
{
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
这时我们发现,除了类型不同,函数体基本完全相同,我们便引入了函数模板。
我们可以定义一个通用的函数模板,而不是为每个类型都定义新函数。代码如下:
template //使用 效果完全一样
int compare(const T &v1, const T &v2)
{
if (v1 < v2) return -1;
if (v1 > v2) return 1;
return 0;
}
<>内表示
模板参数列表 这是一个逗号分隔的多个模板参数的列表,在模板定义中参数列表不能为空
调用模板函数:
float m = 1.5, n = 2.5;
double x = 10.5, y = 20.5;
int a = 1, b = 2;
//模板函数的调用 模板函数默认不作类型转换
compare(m,n); //compare(float,float)
compare(x, y); //compare(double,double)
//compare(a, y); //error
模板函数的实例化:
当调用一个函数模板时,编译器会利用给定的函数实参来推断模板实参,用此实际实参代替模板参数来创建出模板的一个新的实例,也就是一个新函数,这个过程称为实例化。
其他细节:
模板函数为了防止类型出错,所以不会作自动类型转换,比如int转换为float。
编译器会根据函数的第一个参数来实例化对应类型的模板函数,所以当参数的类型不同时,编译器会报错。
例题:
编写一个print函数模板,它接收一个数组的引用,能处理任意大小、任意元素类型的数组
template
void print(const T (&a)[N])
{
for (auto iter = begin(a); iter != end(a); iter++)
{
cout << *iter << "";
}
cout << endl;
}
int main()
{
int a[6] = { 0,1,2,3,4,5 };
print(a);
return 0;
}
类模板:
类模板的定义:
template
class Vector {
public:
Vector(int); //构造函数(int)
~Vector(); //析构
Vector(const Vector&); //拷贝构造函数
Vecotr& operator=(const Vector&); //=运算符重载
T& operator[](int); //[]运算符重载
private:
T* m_elements;
int m_size;
};
类模板中函数的定义:
template
Vector::Vector(int size) :m_size(size)
{
m_elements = new T[m_size];
}
template
T& Vector::operator[](int index)
{
if (index 0)
{
return m_elements[index];
}
else
{
...
}
}