模板形参包含:类型形参,非类型形参
模板实参推断(p538):一般而言,不会转换实参以匹配已有的实例化,相反,会产生新的实例。除了产生新的实例化之外,编译器只会执行两种转换:
类型形参:
声明:typename(或class) T(标识符)
使用时:具体类型如int
非类型形参:
声明:类型说明符(如int,size_t)
使用时:常量表达式(如16)
编写模板代码需注意:
1)模板形参不能为空
2)每个模板类型形参前面必须带上关键字class或typename,每个非类型形参前面必须带上类型名字,省略关键字或类型说明符是错误的
eg:template <typename T,U> T calc(const T&,const U&); //error
模板形参表中,关键字typename和class具有相同含义,使用关键字typename更为直观,毕竟它也能表示内置类型
在模板定义内部指定类型:
template <class Param,class U>
Parm fcn(Param *array,U value)
{
Parm::size_type *p; //如果size_type是个类型,则此句为声明一个指针类型
//如果size_type是个对象,则此句为一个乘法表达式
}
默认情况下,编译器假定这样的名字指定数据成员(即对象),而不是类型
通过在成员名前加上关键字typename作为前缀,可以告诉编译器将成员当做类型:typename Parm::size_type *p;当然这一声明给用来实例化fcn的类型增加一个职责:那些类型必须具有名为size_type的成员,而且该成员是一个类型
注意:如果拿不准是否需要以typename指明一个名字是一个类型,那么指定它是个好主意。在类型之前指定typename没有害处,因此,即使typename是不必要的,也没有关系
函数模板可以用非模板函数一样的方式声明为inline。说明符放在模板形参表之后,返回类型之前,不能放在关键字template之前
template <typename T> inline T min(const T&,const T&);
模板实参推断(p538):一般而言,不会转换实参以匹配已有的实例化,相反,会产生新的实例。除了产生新的实例化之外,编译器只会执行两种转换:
1)const转换:
2)数组或函数到指针的转换
p547使用模板的名字的时候,必须指定模板形参。这一规则有个例外:在类本身的作用域内部,可以使用类模板的非限定名。
例如:Queue (const Queue &Q)= Queue<Type>(const Queue<Type &Q),在这里对类成员函数名和该函数的本类型的参数(注意一定要是本类型),自动会加上模板形参
编译器不会为类中使用的其他模板的模板形参进行这样的推断,因此,在声明伙伴类QueueItem的指针时,必须指定类型形参:
QueueItem<Type> *head;

本文介绍了模板形参的概念,包括类型形参和非类型形参的声明及使用,并探讨了模板定义内部指定类型的方法,以及模板实参推断的规则。
》读书笔记7-第16章 模板与泛型编程&spm=1001.2101.3001.5002&articleId=7614228&d=1&t=3&u=e603670eb87f4d1787cf01fbd30016c5)
496

被折叠的 条评论
为什么被折叠?



