C++模板
《C++ Primer Plus》笔记
函数模板
语法
既可以使用
typename
,也可以使用class
template<typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
template<class T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
函数模板的重载
不同的类型使用不同的处理方式
template<typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
template<class T>
void swap(T a[], T b[], int n) {
T temp;
for(int i = 0; i < n; i++) {
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
模板函数的具体化
函数模板本身不会产生函数定义的方案,编译器使用模板为特定类型生成函数定义时,得到的是模板的实例。
隐式实例化
使用某一种类型调用模板方法时,编译器生成该类型对应的函数定义
template<typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
int a = 1, b = 2;
swap<int>(a, b); // 发生隐式实例化
显示具体化
当提供了显示具体化函数,编译器将不再使用模板函数,函数前使用
template<>
修饰
template<typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
template<> void swap<Job>(Job &job_a, Job &job_b) {
...
}
或者写成:
template<typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
template<> void swap(Job &job_a, Job &job_b) {
...
}
显示具体化
声明所需的种类,使用
<>
来指示类型,并使用template
关键字,可直接命令编译器生成具体的函数定义
template<typename T>
void swap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
template void swap<int>(int &a, int &b); //显示具体化针对int类型的方法
template void swap<Job>(Job &a, Job &b); //显示具体化针对Job类型的方法
针对多个模板方法对应的实例化函数,将通过以下顺序选取最佳匹配
- 完全匹配,但常规函数优先于模板函数
- 提升转换(
char
和short
转int
,float
转double
等)- 用户定义的转换,如类声明定义中的转化等
类模板
类模板定义
template<typename T>
class ClassTest {
private:
T M_property;
public:
ClassTest(T t);
void fun1(T t);
T fun2(T &t);
};
template<typename T>
ClassTest<T>::ClassTest(T t) {
m_property = t;
};
template<typename T>
void ClassTest<T>::fun1(T t) {
...
};
template<typename T>
T ClassTest<T>::fun2(T &t) {
...
};
ClassTest<string> classTest; // 实例化对象
成员模板
模板可用作结构体,类或模板类的成员
template<typename T>
class ClassTest {
private:
template<typename V>
V M_property;
...
};
// 也可写成,但不能写成template<typename T, typename V>
template<typename T>
template<typename T>
class ClassTest {
private:
V M_property;
...
};
模板类作为参数
template <template <typename T> class Type>
class ClassTest {
...
};
当实例化时, Type必须是模板类
template<typename T>
class Test{
...
};
ClassTest<Test> classTest; // 通过编译
ClassTest<int> classTest; // 报错
类模板的具体化
隐式实例化
同函数模板
vector<int> vec; //隐式实例化针对int类型的vector类
显式实例化
同函数模板,使用
template
关键字和<>
, 指定编译器生成对应的具体类
template map<int, string>; // 生成针对int和string类型的map类
显示具体化
针对某一类型定义具体的模板类,同函数模板一样使用
template<>
// 针对Job类型定义具体的模板类
template <> class ClassTest<Job> {
...
};
类模板元友
类模板的元友不一定得是模板方法,模板类为参数的元友必须是模板方法
template<typename T>
class ClassTest{
public:
friend void fun();
friend void fun2(ClassTest<T> c);
};
void fun() {
ClassTest<int> c;
...
}
template<typename T>
void fun2(ClassTest<T> c){
...
}
模板类的约束元友函数
使每一个具体化的类都能生成对应的具体化元友
// 在类前申明模板函数
template<typename T>
void fun(ClassTest<T> c);
template<typename T>
class ClassTest{
public:
// 在类中再次声明为元友
friend void fun<>(ClassTest<T> c); // <>指出其为模板具体化
};
template<typename T>
void fun(ClassTest<T> c){
...
}