前言
模板初阶主要带大家来看看泛型编程,函数模板以及类模板的一些基本使用
一、泛型编程
泛型编程的作用,我们在C++入门的时候提到过,C++支持了重载,但是重载也有一个明显的不好的地方:当出现新的类型的时候需要我们添加对应的函数。如下图的Swap函数。
void Swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
void Swap(char& a, char& b)
{
char tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 1, b = 2;
Swap(a, b);
char a1 = '0', b1 = '2';
Swap(a1, b1);
//那要是还要double,longlong.....
return 0;
}
C++后面提供了泛型编程:
- 编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
于是上面的代码就可以改成下面这样。
template<class T>
void Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 1, b = 2;
Swap(a, b);
char a1 = '0', b1 = '2';
Swap(a1, b1);
cout << a << " " << b << " "<<a1 << " " << b1 << endl;
return 0;
}
二、函数模板
概念: 函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。
用到的关键字template<typename T1,typename T2…>
template<class T>
void Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
typename是定义模板参数的关键字,也可以用class。
注意一点就是函数模板类似于蓝图,实际上如果没有显式的去给定类型,是要经过编译器通过对实参类型的推演,然后生成一份专门处理某种类型的代码。
2.1 编译器不会进行模板类型转换操作
template<class T>
int Add(const T& a,const T& b)
{
return a + b;
}
int main()
{
int a = 1;
double b = 2;
//这里就会发生二义性,编译器不知道T是int还是double,不敢隐式类型转换
//在模板当中编译器一般不会进行类型转换操作,因为一旦失败,编译器要背锅
cout<<Add(a, b);//error
return 0;
}
解决方案:
- 强转类型
- 显式实例化
template<class T>
int Add(const T& a,const T& b)
{
return a + b;
}
int main()
{
int a = 1;
double b = 2;
//显式实例化
cout << Add<int>(a, b);
//强转类型
cout << Add(a, (int)b);
return 0;
}
2.2 非模板可以隐式类型转换
int Add(const int& a, const int& b)
{
return a + b;
}
int main()
{
int a = 1;
double b = 2;
// 实参b给形参b发生隐式类型转换,模板不行,这里可以
cout<<Add(a, b);//b拷贝一个临时变量(tmp),tmp就能给b。
return 0;
}
三、类模板
类模板就不能够隐式实例化了,这是规定,即使你在构造函数使用了模板的参数,也不起作用。
template<class T>
class A
{
public:
A(T a)
:_a(a)
{}
private:
int _a;
};
int main()
{
A a(1);//跑不过
A<int> a(1);
return 0;
}
报错:
需要注意的几点
- 类模板实例化需要在类模板名字后跟<>,然后实例化的类型放在<>中即可
- 类模板名字不是真正的类,而实例化的结果才是真正的类
- 类只能显式实例化
- 模板不支持声明和定义放在两个不同文件(有解决方案)
- 对于普通类,类名就是类型,对于类模板,类型是A< int >
声明定义在一个文件分离时的格式
template<class T>//相当于模板声明
A<T>::A(T a)//指明类是A<int>当中的函数
:_a(a)
{}
int main()
{
//A a(1);//跑不过
A<int> a(1);
return 0;
}
总结
模板初阶就到这啦,下节就开始string,STL的学习啦。
看到这里不妨一键三连。