我们现在要计算int和double类型数据的平方,我们就需要2个函数:
#include <iostream> using namespace std; int square(int x) { return x*x; } double square(double x) { return x*x; } int main() { cout << square(5) << endl; cout << square(5.5) << endl; system("pause"); }
我们完成了任务,但是是用一种非常不方便的方式,如果还要计算long long和float类型的数据平方,我们还需要添加2个函数。
这就是我们为什么需要template。使用template我们只需要1个函数,就能完成所有任务。
#include <iostream> using namespace std; template <class T> T square(T x) { return x*x; } int main() { cout << square<int>(5) << endl; cout << square<double>(5.5) << endl; system("pause"); }
注意:在使用template function时候,我们不必明确指示参数类型,编译器能根据函数的参数自动判断类型。 所以 square(5)和square(5.5)也是正确的写法。
1.template有一个负面效果:code bloat(代码膨胀)
即使我们只有一个template方法。但是由于square(5)和square(5.5)参数类型不一样,在最终的代码中有2个不同的square函数。如果你使用了很多不同类型参数的
square函数,最终的代码size,就会比较大。
下面我们来介绍模版类:class template。
template除了可以用在函数上,也可以在类中使用。编写一个简单的MyVector类。
#include <iostream> using namespace std; template <class T> class MyVector{ int size; T arr[1000]; public: MyVector() : size (0) { } void push(T x) { arr[size] = x; size++; } void print() const { for(int i=0; i<size; i++) cout << arr[i] << endl; } }; /* 在类外部实现函数的写法。 template <class T> void MyVector<T>::push(T x) { arr[size] = x; size++; } */ int main() { MyVector<int> My; My.push(2); My.push(5); My.push(8); My.push(9); My.print(); system("pause"); }
2.不同于模板函数,模版类你必须明确指定类型。
现在我们希望square函数能够作用与MyVector类。 思考:
1.square函数是2个相同类型的相乘,所以我们要重载MyVector类的 *操作符。它的参数是两个MyVector类,返回值是一个新的MyVector类。
所以函数原型如下:
template <class T>
MyVector<T> operator *(const MyVector<T> v1, const MyVector<T> v2)
2.因为square函数是自己乘自己。所以size一定是相同的。
获取size: int getSize() const
获取每个位置的值 T get(int i) const
然后我们把每个位置的值相乘,返回值放在一个新的MyVector中,返回新的MyVector就完成任务。
#include <iostream> using namespace std; template <class T> T square(T x) { return x*x; } template <class T> class MyVector{ int size; T arr[1000]; public: MyVector() : size (0) { } void push(T x) { arr[size] = x; size++; } void print() const { for(int i=0; i<size; i++) cout << arr[i] << endl; } int getSize() const { return size; } T get(int i) const { return arr[i]; } }; template <class T> MyVector<T> operator *(const MyVector<T> &v1, MyVector<T> &v2) { MyVector<T> ret; int size = v1.getSize(); for(int i=0; i<size; i++) { T x = v1.get(i) * v2.get(i); ret.push(x); } return ret; } int main() { MyVector<int> My; My.push(2); My.push(5); My.push(8); My.push(9); My.print(); cout << "After square" << endl; MyVector<int> NewVector; NewVector = square(My); NewVector.print(); system("pause"); }