在c++标准化过程中,引入关键字typename是为了说明:模板内部的标识符可以是一个类型。
template <typename T>
class MyClass{
typename T::SubType* ptr; //SubType是定义于类T内部的一种类型
};
- 通常而言,当某个依赖于模板参数的名称是一个类型时,就应该使用typename
对于那些在基类中的声明,并且依赖于模板参数的符号(函数或变量等),你应该在它们前面使用this->或者Base<T>::
如果希望完全避免不确定性,你可以使用this->和Base<T>::等限定模板中所有的成员访问。
- 对于非引用类型的参数,在实参演绎的过程中,会出现数组到指针(array-to-pointer)的类型转换(decay)
如果遇到一个关于字符数组和字符串指针之间不匹配的问题,解决方法可以视情况使用:
- 使用非引用参数,取代引用参数(注意,这可能会导致无用的拷贝)
- 编写接收引用参数和非引用参数的两个重载函数(注意,这可能会导致二义性)
- 对具体类型进行重载(比如对std::string进行重载)
- 重载数组类型
template <typename T, int N, int M>
T const* max(T const {&a} [N], T const {&b}[M])
{
return a<b?b:a;
}
- 强制要求应用程序猿使用显式类型转换
其他要注意的点:
1、 如果要访问依赖于模板参数的类型名称,应该在类型名称前添加关键字typename
2、 嵌套类和成员函数也可以是模板
3、 针对元素类型可以进行隐式类型转换的模板类,即时实现了通用的复制操作,类型检查依然是存在的
4、 赋值运算符的模板版本并没有取代缺省赋值运算符
5、 类模板也可以作为模板参数,我们称之为模板的模板参数
6、 模板的模板实参必须精确地匹配。匹配时不会考虑“模板的模板实参”的缺省模板实参
7、 通过显式调用缺省构造参数,你可以确保模板的变量和成员都已经用一个缺省值完成初始化,这种方法对内建类型的变量和成员同样适用
8、 对于字符串,在实参演绎的过程中,当且仅当参数不是引用时,才会出现数组到指针(array-to-pointer)的类型转换(称为decay)
网友评论