template可以让编译器帮用户写代码,它将会被编译根据你具体的使用,it makes compiler write some code for you based some rules ,and sounds cool !当你使用模板编程时,编译器为此生成一个框架,当你传入某个具体的参数时,编译器将会根据你传入的参数在事先确定的框架里面写入代码。
为什么需要模板
当我们需要许多函数,其内部执行的操作是相似的,但是我们可能需要接受不同类型的参数,这样的函数就可以写模板
模板函数
只有当调用这个模板时,才会被写进代码(编译的时候写入源码),调用时会根据调用的具体的参数生成对应的代码,以下的函数可以接受任意标准类型的参数
template <typename T>
void print(T value){
std::cout << value << std::endl;
}
我们就可以传入不同类型的参数调用这个函数,模板函数还接受模板参数,比如下面的int,也可不指定模板函数的模板参数,编译器进行自动推导
print<int>(10);
print("hello");
注意当我们没有调用这个函数时,这个函数并不会存在于源码中直到我们调用它,我们甚至可以将源码中变量value更改为valu,而编译并不会报错(在不调用该函数的前提下,在某些编译器下可能也会报错)
template <typename T>
void print(T value){
std::cout << valu << std::endl;
}
当我们将模板函数传入某个具体的参数时,相当于增加了如下的代码,(编译器为我们写入的代码)
void print(int value){
std::cout << value << std::endl;
}
当我们传入不同类型的参数时,编译器会为我们写入对应于不同类型的函数,即这个函数不同类型的多个版本
模板类
假如我们想在栈区声明一个数组,我们可以通过模板参数来指定数组的大小,因为这是在编译时被指定的
template<int N>
class array{
private:
int arr[N];
public:
int GetSize()const {return N};
}
当我们声明一个具体的对象并传入模板参数时
array<5> a;
我们就相当于定义了一个如下的类
class array{
private:
int arr[5];
public:
int GetSize()const {return 5};
}
此外,我们还可以声明多个模板参数,这样我们不仅可以指定数组的大小,我们还可以指定数组所存储元素的具体类型
template <typename T,int N>
class array{
private:
T arr[5];
public:
int GetSize()const {return 5};
}