一、模板函数
先来看一下一个交换两个int类型的参数的函数
void swap(int& x , int& y){
int temp = x;
x = y;
y = temp;
}
如果我们需要去交换floats , string 或 double类型的数据呢?显然,交换不同的参数,函数内部的结构时完全一样的,仅仅时改变一下数据的类型即可。这个时候我们就可以用到模板了。用法如下:
template < class T >
void swap (T& x , T& y)
{
T temp = x;
x = y;
y =temp;
}
int main(){
int a=2; int b = 3;
//这两种调用方法都是可以的, 但对于无参模板函数来说,只能选择第二种 swap<int>();
swap(a,b);
swap<int>(a,b);
return 0 ;
}
- template 这里完成的功能时声明一个函数模板,并不是定义一个函数,确切的说,现在的swap(T& x , T & y)还不能称为是一个函数。 模板的作用就是告诉编译器
如何做出一个函数
来!当程序运行时,比如说遇到了swap(a,b); 假如这里的a和b是double类型,那么编译器就会按照模板来自动生成一个void swap(double& x , double& y){ } 函数来。 - swap(int , double);这种调用是错误的,定义了函数模板之后,编译器将会
杜绝隐式转换
! - 又存在特定的函数又存在函数模板,那么编译器会优先调用特定的函数。(这里的特定的函数指的是程序员自己定义了一个swap,比如说: swap(double & a , double & b){} 而不是让编译器按照模板自动生成)
二、无参数的函数模板:
- 使用方法和模板类几乎相同
显示的调用函数
template < class T >
void foo(){ /***/ }
foo<int> () ; //Type T is int
foo<double>(); //Type T is double
二、模板类
template < class T >
class Vector{
Vector(int);
~Vector();
Vector(const Vector&); //拷贝构造
Vector& operator=( const Vector& );
private:
T* m_elements;
int m_size;
}
使用的方法如下:
Vector<int> v1(100);
Vector<double> v2(256);
类模板中的每个函数成员都是函数模板,每个函数的定义都要加上template , 成员函数的定义方法如下:
template<class T>
Vector<T>::Vector(int size) : m_size(size){
m_elements = new T[m_size];
}
template<class T>
Vector& Vector<T>::operator=(const Vector& ){
}
- 模板类可以有多个参数,并且可以有缺省值,
template <class A , class B>
template <class T , int bounds = 100 >
模板类的继承:
- Templates can inherit from non-template classes
template < class T >
class Deriver : public Base {}
- Templates can inherit from template classes
template<class A>
class Derived : public List<A> { }
- Non-template classes can inherit from templates
class Derived : public List<A> { }