函数模板
template <typename T>
template <class T>可以混用
template <typename T>
void Swap(T& x, T& y)
{
T tmp = x;
x = y;
y = tmp;
}
typename 与class
区别
typename可以在一些特殊场景的使用
typename vector<T>::const_iterator it = v.begin();//告诉编译器 这是个类型,不是静态成员变量
template <class T>
void print(const vector<T>& v)
{
typename vector<T>::const_iterator it = v.begin();//告诉编译器 这是个类型,不是静态成员变量
// vector<T>::const_iterator it = v.begin();//此时类未实例化,
while (it != v.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
int main()
{
vector<int>v(5);
print(v);
return 0;
}
函数模板的实例化
函数模板的实例化分为:隐式实例化,显式实例化
隐式实例化
让编译器根据实参直接推演模板参数
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int Add(int left, int right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.0, d2 = 20.0;
Add(a1, a2);//隐式实例化
Add(d1, d2);
//Add(d1, a1);//隐式实例化存在歧义
Add<int>(a1, d1);//显式实例化
//在函数名和参数之间
return 0;
}
函数模板的匹配原则
一个非模板函数和一个同名的函数模板同时存在
与非模板参数类型完全匹配,优先调用非模板函数
如果模板能生成更好的匹配成果,用模板函数
类模板
Vector类名,Vector<int>才是类型
Vector<int> s1;
Vector<double> s2;
因为没有传参 则不能隐式实例化
显式实例化
template<class T1>
class Stack
{
public:
T1* _a;
};
Stack<int> st1;
声明与定义分离
template <class T>
class Stack
{
public:
T* _a;
void pushback(T* _a);
};
template<class T>
void Stack<T>::pushback(T* _a) //Stack<T>一个类型
{
}
类模板是一个类家族,模板类是通过类模板实例化的具体类
类模板的成员函数都是模板函数