函数模板
Swap模板
函数模板实例化过程
- 模板的推演,推演T的具体类型是什么
- 再实例化生成具体的函数
库里有Swap函数以后直接用
//template<class T>
//template<class T1, class T2, class T3>
//template<typename T>
template<class T>
void Swap(T& x1, T& x2)
{
//T tmp = x1;
T tmp(x1);//拷贝构造
x1 = x2;
x2 = tmp;
}
int main()
{
int a = 0, b = 1;
double c = 1.1, d = 2.2;
Swap(a, b);
Swap(c, d);
char c1 = 'A', c2 = 'a';
Swap(c1, c2);
int* p1 = &a, *p2 = &b;
Swap(p1, p2);
return 0;
}
Add模板
- 通过转换匹配类型来运行
int Add(const int& left, const int& right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.1, d2 = 20.2;
//隐式类型转换
cout << Add(a1, d2) << endl;
}
- 模板需要强转类型或者显示实例化指定T的类型才能运行
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double d1 = 10.1, d2 = 20.2;
// 实参去推演形参的类型
cout << Add(a1, a2) << endl;
cout << Add(d1, d2) << endl;
cout << Add(a1, (int)d2) << endl;
cout << Add((double)a1, d2) << endl;
// 不需要推演,显示实例化指定T的类型
cout << Add<int>(a1, d2) << endl;
cout << Add<double>(a1, d2) << endl;
}
- 显示实例化
template<class T>
T func(int x)
{
T a(x);
return a;
}
int main()
{
// func(1);--err
// 有些函数模板里面参数中没用模板参数,函数体内才有用
// 无法通过参数推演T的类型,只能显示实例化
func<A>(1);
func<int>(1);
}
模板匹配原则:
- 有现成完全匹配的,那就直接调用,没有现成调用的,实例化模板生成
- 有需要转换匹配,那么它会优先选择去实例化模板生成
- 完全普配 > 模板 > 转换匹配 – 调用
//专门处理int的加法函数
int Add(int left, int right)
{
return left + right;
}
// 通用加法函数
template<class T>
T Add(T left, T right)
{
return left + right;
}
int main()
{
//有现成完全匹配的那就直接调用,没有现成调用的,实例化模板生成
//若没有模板则调用专门处理int的函数进行转换匹配
Add(1, 2);
Add<int>(1, 2);
// 有需要转换匹配--优先选择实例化模板生成,没有模板才会使用int的(隐式类型转换)
Add(1.1, 2.2);
return 0;
}
类模板
c语言
typedef int STDataType;
class Stackint
{
private:
STDataType* _a;
int _top;
int _capacity;
};
class Stackdouble
{
private:
STDataType* _a;
int _top;
int _capacity;
};
int main()
{
Stack st1; // int
Stack st2; // double
return 0;
}
C++使用类模板更加方便
- 类模板的使用不通过推演,都是使用显示实例化指定的类型
- 模板不支持声明写到.h,定义写到cpp,会报理解错误
struct TreeNode
{
// ...
};
template<class T>
class Stack
{
public:
Stack(int capacity = 4)
:_a(new T[capacity])
, _top(0)
, _capacity(capacity)
{}
~Stack()
{
delete[] _a;
_a = nullptr;
_top = _capacity = 0;
}
// 类里面声明,类外面定义
void Push(const T& x);//只插入数据不改变x用const
private:
T* _a;
int _top;
int _capacity;
};
// 普通类,类名就是类型
// 类模板,类名不是类型,类型是Stack<T>
template<class T>
void Stack<T>::Push(const T& x)
{
// ...
}
int main()
{
// 类模板的使用都是显示实例化--因为没有办法指定T
Stack<TreeNode*> st1; // TreeNode*
Stack<int> st2; // int
st2.Push(1);
return 0;
}