三、模板的其他特性
1.缺省参数
(1)类模板的模板参数可以带有缺省值,实例化该模板时,如果提供了相应的实参,则忽略缺省值,反之则以缺省作为对应形参的值.
(2)如果某个模板参数带有缺省值,那么它后面的所有参数都必须带有缺省值
(3)C++98 不允许为函数模板的模板参数指定缺省值 <尖括号里面的> 。 C++11 允许。
gcc < 4.8: -sts=c++0x gcc >= 4.8: -std=c++11
(4)对于函数模板,如果模板参数的缺省值与隐式推断的类型不一致,以隐式推断的类型为准,忽略其缺省值.===>C++11标准下
参见:default.cpp
2.非类型参数
(1)模板处理可以接收类型参数以外,也可以接受非类型参数,即数值参数,非类型参数不能用typename声明,而要注明其具体类型,而且传递给模板非类型参数的实参必须是常量,常量表达式,或者带有常属性(const,C限定)的变量,但是不能同时具有挥发性(volatitl,V限定).
(2)向模板传递字符串形式的非类型参数:形参必须使用字符指针,实参必须使用非静态全局字符数组
(3)模板的费诶性参数只能使用证书类型:[signed/unsigned]char/short/int/long/long long,不能使用double/float等浮点类型! (只有当程序 运行的时候,才会激活CPU中的浮点处理器,编译的阶段不会处理)
3.typename关键字
在模板参数被实例化之前,模板参数所表示的具体类型并不确定,编译器会把依赖于模板参数的嵌套(内部)类型理解为某个类的静态成员变量,当其”看到”用该变量定义其他变量的代码时,会报告错误.
typename关键字可以”告诉”编译器,其后的标识符不是静态成员变量,而是某种类型,编译器就会将有关该编制福的类型检查,推迟到模板实例化的过程中,避免编译错误---------解决嵌套依赖
-
class关键字:1)声明类 (2)声明模板的类型参数
-
typename关键字:(1)解决嵌套依赖 (2)声明模板的类型参数
-
struct关键字:声明类
-
struct声明的类默认是公有的,class声明的类默认是私有的
参见代码:typename.cpp
4.template 关键字作用
(1)声明函数模板和类模板
template<..>
(2)解决嵌套模板:
- 依赖于模板参数的类型的内部模板
- 在模板代码中,通过依赖于模板参数的对象,引用,或指针,访问其带有模板特性的成员需要使用template关键字显示指明其后的名称是一个模板,避免编译器将模板参数表的左右尖括号理解为小于号和大于号,导致编译失败
参见:template.cpp、
5、子类模板访问基类模板
在子类模板中访问那些在基类模板中声明且依赖于模板参数的符号,应该在它前面加上作用域限定符"::" 或者显示使用this指针否则,编译器将试图在全局域中寻找该符号,引发错误。
参见:inherit.h
6.模板型模板参数
类模板的模板参数如果结合的实参不是具体类型而是另一个模板,那么不能使用typename关键字声明该参数,而是写明其所结合的类模板实参的原型:
template<模板形参表> class 模板型模板参数名
参见ta.cpp
对于函数模板,GNU编译器允许为其传递模板型模板参数,但是从C++标准并不支持。
7.嵌套模板的外部定义
如果将嵌套于一个类模板的内部模板放到包装模板的外部定义,需要按照作用域层次的顺序,从外到内,从前到后一次使用独立template字句声明其模板参数表
8.“零”初始化
基本类型不存在缺省构造函数,所以未被显示初始化的局部变量和成员变量具有一个未定义的初值。如果希望模板函数或者模板类中所有参数花类型的变量,无论是基本类型还是类类型,都能以缺省方式被初始化,就必须显示进行缺省构造(写出构造函数),即“零”初始化。
T var = T(); //局部变量
...:m_var()...//成员变量
参见:init.cpp
9.虚函数和多态
(1)类模板中可以声明虚函数,而且只要实例化该模板时所提供的类型实参不违背虚函数有效覆盖的条件,就可以形成多态
(2)由于模板函数的延迟编译要晚于类或者类模板中虚表的构建,因此模板函数不能同时又是虚函数
参见vf.cpp
列出不能被声明为虚函数的函数:
全局函数,静态成员函数,构造函数,模板型成员函数
本文详细探讨了C++模板的高级特性,包括缺省参数、非类型参数、typename关键字、template关键字的作用、子类模板访问基类模板、模板型模板参数、嵌套模板的外部定义、“零”初始化、虚函数和多态等。通过实例和代码,帮助读者深入理解模板的使用和优化。
1万+

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



