C++---------模板
模板
分类:函数模板和类模板
函数模板:
概念:函数模板代表了一个函数家族,该函数模板和类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
注:函数模板不是真正的函数,它是编译器生成代码的规则
1:函数模板格式template返回值类型 函数名(参数列表){}
2:函数模板的原理:模板是一个蓝图,它本身不是类或函数,编译器用模板产生指定的类或函数的特定类型版本,产生模板特定类型的过程称为函数模板实例化。
注:在不同类型参数传递给函数模板时,编译器需要根据传入的实际参数类型,来推演生成对应类型的函数供调用,简言之,本来我们做的函数编码工作,交给编译器去做了。
下面是函数模板的例子:
#include <iostream>
#include<windows.h>
using namespace std;
#if 1
// 函数模板不是真正的函数,它是编译器生成代码的规则
template<class T>
T Add(T left, T right)
{
cout << typeid(left).name() << endl;//typeid在C++中用于获知一个变量的具体类型
return left + right;
}
int main()
{
cout << Add(1, 2) << endl; // T---> int:int Add(int , int)
cout << Add(1.0, 2.0) << endl; // T---> double: double Add(double, double)
cout << Add('1', '2') << endl; // T---> char: char Add(char, char)
cout << Add(1, (int)'1') << endl;//字符1对应的十进制是49
cout << Add<int>(1, '1') << endl;
system("pause");
return 0;
}
#endif
模板参数列表也可以定义多个类型,下面用代码展示:
#if 1
int Add(int left, int right)
{
return left + right;
}
template<class T1, class T2>
T1 Add(T1 left, T2 right)//两个类型
{
cout << typeid(left).name() << endl;
return left + right;
}
int main()
{
Add(1, 2);
Add<>(1, 2);
Add(1, '1');
system("pause");
return 0;
}
#endif
3:模板参数的实例化
下面用代码展示:
template<class T1, class T2>
T1 Add(T1 left, T2 right)
{
cout << typeid(left).name() << endl;
return left + right;
}
int main()
{
Add(1, 2);//隐式实例化
Add<int>(1, 2);//显示实例化
//Add(1, '1');
system("pause");
return 0;
}
注:1:一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数;
2:对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而不会从该模板产
3:生出一个实例。如果模板可以产生一个具有更好匹配的函数, 那么将选择模板;
4:显式指定一个空的模板实参列表,该语法告诉编译器只有模板才能来匹配这个调用, 而且所有的模板参数都
应该根据实参演绎出来
5:模板函数不允许自动类型转换,但普通函数可以进行自动类型转换
类模板:
类模板的定义格式
类模板的格式:
template
class 类名
{ ... };
2. 实例讲解
template<typename T>
class MyVector
{
public :
MyVector();
~MyVector();
private :
int _size ;
int _capacity ;
T* _data ;
};
template <typename T>
MyVector <T>:: MyVector()
: _size(0)
, _capacity(10)
, _data(new T[ _capacity])
{}
template <typename T>
MyVector <T>::~ MyVector()
{
delete [] _data ;
}
void test1 ()
{
MyVector<int > sl1;
MyVector<double > sl2;
}
3. 类模板按需实例化
类模板是用来生成类的蓝图。与函数模板不同之处是,编译器不能为类模板推断模板参数类型。
为了使用类模板,我们必须在类模板名后的尖括号中提供额外信息,用来替代模板参数的模板实参列表。
从之前的代码例子中可以看到, MyVector类模板是根据需要使用的类型,具体给出了实例化时的类型:
MyVector sl1; MyVector sl2;