简述
-
类模板:是类类型的模板,如:
vector
。 -
模板类:类模板的实例化,如:
vector<int>
。 - 类模板的模板参数无法通过模板参数自动推断来确定,必须显式指定。
定义
类模板的定义和声明必须放在头文件中
template<typename T>
class A {
public:
A();
void fun1();
void fun2() {} // 定义在模板内部
};
template<typename T>
A<T>::A() {
}
template<typename T>
void A<T>::fun1() {
}
特化
代码
template <typename T>
class A {
public:
A() { std::cout << "A<T>" << std::endl; }
};
template <>
class A<double> {
public:
A() { std::cout << "A<double>" << std::endl; }
};
int main() {
A<int> a1;
A<double> a2;
return system("pause");
}
输出结果
A<T>
A<double>
特化成员函数
template <typename T>
class A {
public:
void fun() {
std::cout << "A<T>::fun()" << std::endl;
}
};
// 只特化类模板的部分成员
template <>
void A<int>::fun() {
std::cout << "A<int>::fun()" << std::endl;
}
前置声明与友元声明
// 前置声明不需要给出模板参数
template <typename> class A1;
template <typename> class A2;
template <typename T>
class B {
public:
friend class A1<T>; // 一对一友元关系
friend class A2<int>; // 多对某一友元关系
template <typename> friend class A3; // 多对多友元关系,也有前置声明的作用
};
// 类模板的特化
template <>
class B<int> {
public:
friend class A2<int>; // 某一对某一友元关系
template <typename> friend class A3; // 某一对多友元关系,也有前置声明的作用
};
可以省略模板实参的情况
template <typename T>
class A {
public:
// 类模板作用域内可以直接使用类模板名字而不必提供模板参数
// 即模板作用域内直接使用类模板名A时,编译期会解读为A<T>
A fun1(A a) {
A b;
return b;
}
A fun2(A a);
};
// 类模板作用域外不可以直接使用类模板名A取代A<T>
template <typename T>
A<T> A<T>::fun2(A a) {
// 类模板成员函数的形参列表及其函数体属于类模板作用域内
A b;
return b;
}
模板类型别名
template <typename T> using name1 = pair<T, T>;
template <typename T> using name2 = pair<T, char>;
int main() {
name1<int> t1; // t1是一个pair<int, int>
name2<int> t2; // t2是一个pair<int, char>
return system("pause");
}
使用模板参数的类型成员
class A {
public:
typedef int value_type;
};
template <typename T>
class B {
public:
typedef typename T::value_type type;
typename T::value_type fun() {
return typename T::value_type();
}
};
默认模板实参
template <typename T = int, typename F = double>
class A {
};
int main() {
A<> a1; // A<int, double>
A<double> a2; // A<double, double>
A<string, string> a3; // A<string, string>
return system("pause");
}
显式实例化
显式实例化类模板时会显式实例化其所有成员。
// 显式实例化的作用是避免编译器多次重复实例化啊,可以达到加快编译速度的效果
// 下述代码不能同时出现在一个文件中
template class A<int>; // 定义,代表在此处将类模板A实例化为A<int>
extern template class A<int>; // 声明,代表承诺在别的文件中有个A<int>实例化