如何将类模板应用于生成?
摘要:基本概念 跟函数模板类似,类模板是用于创建具有相同行为接口(算法一致)但数据类型不同的类的蓝图。 核心逻辑:类的行为(成员函数、操作逻辑)与存储的数据类型无关,仅需定义一次模板,即可适配多种数据类型。 典型示例 链表类、栈类、队列类等容器类
基本概念
跟函数模板类似,类模板是用于创建具有相同行为接口(算法一致)但数据类型不同的类的蓝图。
核心逻辑:类的行为(成员函数、操作逻辑)与存储的数据类型无关,仅需定义一次模板,即可适配多种数据类型。
典型示例
链表类、栈类、队列类等容器类:
核心操作(插入、删除、检索、合并)与存储的数据类型无关
通过类模板可快速实现支持 int、string、自定义类型等多种数据的容器,无需重复编写类代码
类模板的定义
核心关键字
template:声明模板的关键字
typename:指定类型参数(旧标准可用 class,功能一致,推荐用 typename 更清晰)
语法格式
// 类模板定义(支持多个类型参数)
template <typename T1, typename T2> // T1、T2 为类型参数(占位符)
class node
{
public:
// 成员函数(可直接在类内实现)
node(){cout << "通用版本" << endl;}
private:
T1 a; // 用类型参数定义成员变量
T2 b;
};
关键注意事项
创建对象时,类型参数列表不可省略(与函数模板不同):// 正确:显式指定类型参数
node<short, double> a;
node<int, string> b;
// 错误:未指定类型参数
// node c; // 编译报错,编译器无法推断类型
类型参数可自定义名称(如 T、Type、Data 等),遵循标识符命名规则
类模板仅为“设计蓝图”,未实例化前不会生成具体代码
类模板的特化
当通用模板无法满足特定类型的需求时,为该类型提供专门的实现版本,称为模板特化。分为「偏特化」和「全特化」。
偏特化(部分类型参数特化)
定义
仅特化类模板中的部分类型参数,剩余参数仍为模板参数。
示例(基于上述 node 模板)
// 偏特化1:第一个参数为 string,第二个参数保留模板参数 T
template <typename T>
class node<string, T>
{
public:
node(){cout << "偏特化(第一个参数为 string)" << endl;}
private:
string a;
T b;
};
// 偏特化2:第二个参数为 string,第一个参数保留模板参数 T
template <typename T>
class node<T, string>
{
public:
node(){cout << "偏特化(第二个参数为 string)" << endl;}
private:
T a;
string b;
};
关键注意事项
特化版本的类声明必须指明已特化的类型(如 <T, string>)
二义性问题:当多个偏特化版本都能匹配同一类型组合时,编译报错// 错误示例:两个偏特化版本都能匹配 node<string, string>
int main(void)
{
node<string, string> n; // 编译报错,二义性
}
报错信息:error: ambiguous template instantiation for 'class node<std::cxx11::basic_string<char>, std::cxx11::basic_string<char>>'
candidates are:
template<class T1> class node<T1, std::_cxx11::basic_string<char>>
template<class T2> class node<std::_cxx11::basic_string<char>, T2>
全特化(所有类型参数特化)
定义
特化类模板中的全部类型参数,无剩余模板参数。
