本文共 2041 字,大约阅读时间需要 6 分钟。
可以对类型进行参数化
templatetemplate
在模板定义中,模板的参数不能为空,因为后面还有模板的特例化,在特例化中模板的参数为空。
一般来说,我们可以将类型参数看作类型说明符,就像内置类型或类类型说明符一样使用。特别是,类型参数可以用来指定返回类型或函数的参数类型,以及在函数体内用于变量声明或类型转换,
除了定义类型参数,还可以在模板定义中定义非类型参数。一个非类型参数表示一个值而非一个类型。我们通过一个特定的类型名而非关键字class 或 typename来指定非类型参数。
当一个模板被实例化时,非类型参数被一个用户提供的或编译器推断出的值所代替。这些值必须是常量表达式,从而允许编译器在编译时实例化模板//定义一个模板函数templateT add(T a,T b){ return a + b;}int main(){ //参数列表为整型,模板会自动推导出T 类型 //这里只有一个模板参数,如果传入的两个值得类型相同,则T类型为传入值的类型 //如果传入的两个值的类型不相同,则编译出错,例如 int a = add(1, 2.232); int a = add(1,2);}
函数模板是前面我们定义的那部分代码,模板的代码是不编译的,只有将模板实例化为模板函数的时候,才对模板函数进行编译。所以,模板的定义与函数模板的调用不能再不同的文件中,因为如果不在同一个文件中,模板不编译,在进行模板的实例化的过程中,找不到模板的定义就会报错。
经过实例化后的的函数叫做模板函数。模板本身不编译,实例化以后才编译在前面的实例化中我们也可以看出,模板在进行实例化的时候会根据传入的参数来推演出参数的类型。当时对于同一个模板参数不能传入不同的参数类型
模板的特例化就是给出模板的特殊的参数类型的处理方式
例如templateT max(T a,T b){ return a + b;}int main(){ int a = max (1,2);}
在这个模板类型中,我们求传入的两个变量的最大值,但是如果传入的两个变量是字符串,我门就不能直接让两个值进行比较了,这时候可以提供模板的特例化版本
templatebool max(T a,T b){ return a + b;}template<> //此处的模板参数列表为空bool max (char *a,char *b){ return strcmp(a,b) > 0;}int main(){ max(1,2);}
在特例化之前,必须要有模板的定义。
通过一段代码来解释
templatebool max(T a,T b){ return a + b;}template<> //此处的模板参数列表为空bool max (char *a,char *b){ return strcmp(a,b) > 0;}bool max(int a,int b){ return a > b;}int main(){ //直接调用的且参数类型匹配的优先选择非模板函数 //如果类型与普通函数相同,则优先调用普通函数 max(1,2); //参数类型既与普通函数不同,也不能实例化模板,则选择调用普通函数 //调用普通函数进行类型的转换,如果选择模板,编译都不会通过 max(1.1,1); //普通函数类型无法匹配,但是模板类型可以匹配,所以选择模板实例化 max(1.1,1.1) //显示调用模板 max (1,2); //如果给的参数与特例化的参数相同,则优先调用特例化 max ("asd","qwe"); return 0}
templateclass A{ public: void fun();private: int mdata;};//在类外定义成员函数的时候加上模板的参数列表template void A ::fun(){ ...}int main(){ A a; //使用类模板创建对象}
函数模板允许隐式调用和显式调用而类模板只能显示调用这期间有涉及到函数模板与模板函数
转载地址:http://htnwi.baihongyu.com/