本章主要针对于函数模板做一个初步的总结,补全了一些C++ Prime上缺失的问题;
函数实参类型转换问题:
在指定模板类型之后,实例化如果类型出现不符合,会进行报错,所以特定场合需要进行类型转换:
#include<iostream> #include<stdio.h> #include<string> using namespace std; template <typename T> inline const T& rmax(const T& a, const T& b) { if (a > b) return a; else return b; } template <typename T, typename U> inline const T& rmax(const T& a, const U& b) { cout << a << endl << b << endl; if (a > b) return a; else return b; } int main() { cout << rmax(1, 2) << endl; //通过直接显式指定ramx得type为int,直接进行显示转换; cout << rmax<int>(1, 2.2) << endl; //使用static_cast来进行转换 cout << rmax(static_cast<double>(4), 2.2)<<endl; //使用多个模板参数来进行定义; cout << rmax(22.22, 4) << endl; system("pause"); return 0; }
上述给出了三种最常见的转换方法:
1.使用static_cast进行强制类型转换;
2.使用显示指定type得类型进行转换;
3.使用多参数模板进行转换;
类模板特化问题:
C++ prime上并没有很清晰的讲解特化问题,这本书做了一个比较基础的介绍;
特化的意义:旨在指定一些参数,使得用处比较广泛的模板变成一些特定参数匹配的模板,有助于某一功能得更好实现;
但是注意:模板的特化只能针对于类模板,而不能针对于函数模板;
特化主要分为三类:
1.全特化;
2.局部特化(网上又称为偏特化);
3.不特化(即最原始的模板写法);
不特化:
即最简单的模板形式,各种模板类型匹配由实际实例化时让程序员给出;
局部特化:
对于多个模板参数,现实化的指定出一些参数类型,可以很好的用于模板匹配的情况;
template <typename T> class myclass<T, T> { //类型一 }; template <typename T> class myclass<T, int> { //类型二 }; template <typename T,typename U> class myclass <T*,U*>{ //类型三 };
上述可以清楚得看到三种类型的定义形式;
所以可以很直白的看到,局部特化本质上就是扩充模板函数,相当于为了重载来进行更好的服务;
并且值得注意的是,在实际使用模板参数的时候,给出的个数往往是类名后面得参数个数,编译器会根据最合适的模板进行实例化;
全特化:
对于全特化,这是局部特化的升级模式,相当于直接指定类模板参数;
template <> class myclass<string, int> { };
可以很清晰的看到,实际上就是第一个参数列表直接为空,在类名后面的参数列表中给予指定;
缺省模板实参问题:
可以通过缺省模板实参方法来在不给定模板参数的情况下进行构造,也可以指定参数,来提高灵活性;
template <typename T, typename CONT = std::vector<T>> class stack { private: CONT elems; };
可以参照书上得分stack定义来看;
如果使用该定义形式可以将stack类内部管理的数据结构进行指定,也可以不指定,不指定直接视为针对于T的vector实例化;