1.模板概念
我们要写交换两个数的函数(但是类型不同),直接写,每种类型要写一个函数,太麻烦了,C的方法我们可以用宏函数解决,但是还是有点麻烦,有没有更简单一点的,C++给我们提供了一种方式就是模板
template <typename T>//tmplate<class T>也可以暂且认为一样
void swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
int main(void) {
int a = 3;
int b = 4;
double c= 1.2;
double d = 3.4;
swap(a, b);
swap(c, d);//这次和上一次调用的不是同一个函数
return 0;
}
2.模板特征
1.模板参数定义的是类型
2.两次调用的不是同一个函数,tmplate只是一个模板,调用的是函数模板生成的函数。
当然如果你要处理两个不一样的类型,就可以这样写
template <class T1,class T2>
void swap(T1& a, T2& b)
{
cout << "12345" << endl;
}
//这样不管是两个一样的类型还是两个不一样的类型,都可以使用这个函数了!
此外,函数模板可以根据调用推导模板参数的类型,实例化出对应的函数
template <class T1>
T1 sxap(T1 a, T1 b)
{
return a + b;
}
int main(void) {
int a = 3;
int b = 4;
double c= 1.2;
double d = 3.4;
cout<<swap(a, c)<<endl;//无法推断
cout <<sxap((double)a, c)<<endl;//强制类型转换
cout << sxap(a, (int)(c)) << endl;
cout << sxap<double>(a, c);//显示实例化,用在指定类型实例化
return 0;
}
我们可以通过强制转化和指定实例化去解决模板无法推导的情况
显示实例化其实在模板类中用的最多
class date
{
public:
date(T1 year=1 )
:_year(year)
{
cout << "hi" << endl;
}
public:
void print(T1 month = 0);
private:
T1 _year = 3;
};
3.类型和类名
普通类,类名和类型是一样的
模板类,类名和类型不一样
template <class T1>
void date<T1>:: print(T1 month)
{
cout << "month" << endl;
}
像我把这个模板类的函数在类外面定义,类名date,类型date<T>
4.对内置类型的影响
但是其实那你会发现我们后面在实现vector resize的时候
void resize(size_t n, const T& val = T())
{
if (n < size())
{
_finish = _start + n;
}
else
{
reserve(n);
while (_finish != _start + n)
{
*_finish = val;
++_finish;
}
}
}
你会发现这个地方如果是data time这样的类型我们好理解回去调用他们的默认构造
但是对于内置类型就难理解了 比如T是int的时候这个地方值应该是多少呢?
因此有了模板以后C++对内置类型做了特殊处理升级 内置类型也有构造函数
像下面这样的代码也是可行的,同样对于其他内置类型都适用
比如double的默认构造是0.0 指针的默认构造是空
int i = int();
int j = int(1);