1. 类模板的基本范例和模板参数的推断
基本范例:
类模板,也是生产类的工具,通过给定的模板参数,生成具体的类。类模板的声明和实现一般都放在同一个头文件中,因为实例化的时候必须有类模板的全部信息。
template<typename T> // T表示myvector这个容器所存储的元素类型
class myvector {
public:
typedef T* myiterator;
public:
myvector();
myvector& operator=(const myvector&);
public:
void myfunc() {
cout << "myfunc()被调用" << endl;
}
public:
myiterator mybegin();
myiterator myend();
};
template<typename T>
myvector<T>::myvector() {} //类外构造函数的实现
int main() {
myvector<int> tmpvec;
tmpvec.myfunc();
}
上述在类模板myvector定义之外写构造函数的实现体时,myvector<T>::myvector()
中::左侧是类型名,右侧是类名。如果在类模板内部,则类型名可以简写成类名,如myvector& operator=(const myvector&);
,如果写完整,应该是myvector<T>& operator=(const myvector&);
在main()主函数中,类型名中的模板参数(int)不能省略,这不同于函数模板某些模板参数可以省略,依靠推断解决。
在类模板中,调用成员函数与调用一个类的成员函数没有区别,直接调用即可。但成员函数只有被调用的时候才会实例化,如果类模板中有静态成员函数,静态成员函数也会在调用的时候被实例化。
模板参数的推断:
在C++17标准中,类模板的类型模板参数变得也可以推断。
template<typename T>
struct A {
A(T val1, T val2) {
cout << "..." << endl;
}
A(T val) {
cout << "..." << endl;
}
};
int main() {
A obj1(15, 16);
A obj2(12.8);
}
对于类模板A的每个构造函数,都有一个隐式的模板参数推断机制存在,称为隐式的推断指南,形式如下:
template<typename T>
A(T, T) -> A(T);
首先,第一行把类模板的参数复制过来,第二行用->分成两部分并以分号结尾。表示出现->左侧部分内容或形式时,请推断成->右侧的类型含义。
类模板的特化
类模板的全特化:
先看一下类模板的泛化版本:
template<typename T, typename U>
struct TC{
TC() {
cout << "..." << endl;
}
void functest() {
cout << "..." << endl;
}
};
所谓全特化,就是把泛化版本中的所有模板参数都用具体的类型代替,在书写全特化版本时,template后的<>变为空。
template<>
struct TC<int, int> {
TC() {
cout << "..." << endl;
}
void functest() {
cout << "..." << endl;
}
};
这里要注意的时,如果functest()函数放在类外去写,应当是如下形式:
// template<> 注意不需要使用这行,否则会语法发错
void TC<int, int>::functest() {
cout << "..." << endl;
}
普通成员函数的全特化:
template<typename T, typename U>
struct TC{
TC() {
cout << "..." << endl;
}
void functest() {
cout << "泛化版本" << endl;
}
};
template<> // 普通成员函数的全特化从本行开始
void TC<double, int>::functest() {
cout << "特化版本" << endl;
}
如果在main()函数中添加新代码:
TC<double, int> mytc;
mytc.functest();
特化版本的成员函数将会取代泛化版本的被调用。
类模板的偏特化:
全特化是把所有类型参数都用具体类型代表。而偏特化可以从两个方面理解,一个是模板参数数量上的偏特化,一个是模板范围上的偏特化。
- 模板参数数量上的偏特化:
template<typename T>
struct TC<float, U> {
TC() {
cout << "..." << endl;
}
void functest();
};
template<typename U>
void TC<float, U>::functest() {
cout << "..." << endl;
}
- 模板参数范围上的偏特化:
所谓参数范围指的是原来是int类型,如果现在变成const int类型(与int相比范围更窄了)。其它诸如从任意类型T缩小为指针类型T*,T&,T&&。
template<typename T, typename U>
struct TC<const T, U*> {
TC() {
cout << "..." << endl;
}
void functest();
};
template<typename T, typename U>
void TC<const T, U*>::functest() {
cout << "..." << endl;
}
标签:myvector,cout,template,TC,模板,特化 From: https://www.cnblogs.com/love-9/p/18104786