我认为的模板其实就是个懒人工具,你来弄个模板,编译器自动给你生成对应的函数。
函数模板:
定义:函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。所以其实模板就是将本来应该我们做的重复的事情交给了编译器。
我们来举个加法的例子:
基本写法:
template<typename T>
T add( T& x, T& y)
{return x+y;
}
格式类似于:
template<typename T1, typename T2,......,typename Tn>
返回值类型 函数名(参数列表){}
注意:typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
这就是我们最简单的写法,我们怎么用呢?
template<typename T>
T add(T x, T y)
{return x + y;
}int main()
{cout <<add(1, 2)<<endl;cout << add(1.1, 2.) << endl;return 0;
}
结果:
匹配机制:
对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板。
例如:
int Add(int left, int right)
{return left + right;
}// 通用加法函数
template<class T1, class T2>
auto Add(T1 left, T2 right)
{return left + right;
}void Test()
{cout<<Add(1, 2)<<endl; // 与非函数模板类型完全匹配,不需要函数模板实例化cout<<Add(1, 2.1)<<endl; // 模板函数可以生成更加匹配的版本,编译器根据实参生成更加匹配的Add
}int main()
{Test();return 0;
}
运行结果:
类模板:
基本定义:
template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
注意:我们类模板不建议定义和声明到两个.h和.cpp文件里面,如果想分离一般都在.h文件进行,一般这样写:
template<typename T>
class Sql
{
public:Sql(int x=4);
private:T* _data;int size;int capacity;
};template<typename T >
Sql<T>::Sql(int x)
{_data = new T[x];_capacity = 0;_size = 0;
}
模板注意:
1.模板运行时不检查数据类型,也不保证类型安全,相当于类型的宏替换。
2.类模板是一个类家族,模板类是通过类模板实例化的具体类。
3.模板是代码复用的重要手段。
4..模板类是一个家族,编译器的处理会分别进行两次编译,其处理过程跟普通类不一样。