C++ 的template编程对于代码具有很高的重复利用率。
template的基本用法:template<class T>/template<typename T>(一般推荐用法)
下面介绍class和typename的区别:在模板参数列表中,这两种方式是相同的,但是在一些场合,typename有其特有的作用,即在嵌套类型说明是需要用typename说明后面的符号为类型而不是成员名称等;参考:
http://blog.163.com/susu_sf/blog/static/171060253201092233759957/
模板的作用就是用一个模板类型T来代替实际的类型,这样只要有相应的函数实例,通过实例的类型就可以将T变成实例。
模板参数和作用域:模板参数遵循普通的作用域规则,一个模板参数名的可用范围是其声明之后,至模板声明或定义结束之前,模板参数会隐藏外层作用域中声明的相同名字的模板名,在模板内不能重用模板参数名;
模板的声明也是必须要包含模板参数,即定义和声明不再一块的话,声明时要有模板参数,定义时也要有。
#include <iostream>
using namespace std;
template <typename T> //声明需要模板参数
int compare(const T &v1,const T &v2);
template <typename T> T sum(T s1,T s2) {return s1+s2;} //可以这样写,空一格再写函数
int main(){
int v1 = 10,v2 = 11;
double d1 = 0.5, d2 = 1.7;
int result,result1;
double result2;
result = compare(v1,v2);
result1 = sum(v1,v2);
result2 = sum(d1,d2);
cout << result << endl;
cout << result1 << endl;
cout << result2 << endl;
}
template <typename T> //定义时也要有模板参数
int compare(const T &v1,const T &v2){ //作用范围有限
if(v1<v2) return -1;
if(v1>v2) return 1;
if(v1==v2) return 0;
}
使用template时需要注意的问题:
- C++中template类定义和声明不能分开,需要写在一个文件中,模板类继承和一般类继承也有区别,子类不能直接访问父类的成员变量。
- template的作用域是有限的,对于模板类来说从类定义开始到最后的结束大括号为作用域,模板函数的话作用域为函数的定义到结束大括号。
- 在模板类或函数内部可以继续定义模板,使用方法相同,不过在作用域在内部而已。
- 模板中类型也可以使用非型别参数,但是非型别模版参数必须是整型或者和整型兼容的如unsigned int,short等;如:
template<class T, int n>
;int n 就是非型别模板参数,它是有特定类型的值。 - C++中的模板函数,模板参数是由函数参数来推导的,而不是函数的返回值。因此当函数没有参数时,是不可以使用模板类型当作返回类型的,因为这样无法推断出实际类型
template<typename T> T value(){}
,只有在value函数有T类型的参数时在实际调用的过程中就会根据实际的参数推导返回类型,上面这种如果想要调用成功需要显示指定类型:value<T>()
。