当前位置: 首页 > java >正文

C++ 中类模板参数的使用详解

1. 什么是类模板?

在 C++ 中,类模板(Class Template) 是一种定义类的通用方式,它允许我们在定义类时将类型(Type)或数值参数化,这样同一份代码可以适配不同的数据类型和常量值,从而提高代码的 复用性灵活性

类模板的定义语法一般为:

template <typename T>
class ClassName {// 类成员定义
};

其中,typename(或 class)引入了一个类型参数 T,在实例化时由用户指定具体的类型。


2. 类模板的参数类型

类模板参数主要分为三类:

2.1 类型参数(Type Parameter)

这是最常用的模板参数类型,用来在编译期间传入类型。

示例:

#include <iostream>
using namespace std;template <typename T>
class MyContainer {
private:T data;
public:MyContainer(T value) : data(value) {}void show() { cout << data << endl; }
};int main() {MyContainer<int> c1(42);       // 传入 int 类型MyContainer<string> c2("Hi");  // 传入 std::string 类型c1.show();  // 输出 42c2.show();  // 输出 Hi
}

说明:

  • T 是类型参数,在实例化类时会被替换成实际类型。
  • 实例化时 MyContainer<int>MyContainer<string> 是两个不同的类类型。

2.2 非类型参数(Non-type Parameter)

除了类型参数,模板也可以接受常量作为参数,比如整型、枚举、指针等(C++20 之后也可以用浮点数、字符串字面量)。

示例:

#include <iostream>
using namespace std;template <typename T, int Size>
class Array {
private:T arr[Size];
public:void set(int index, T value) {if (index >= 0 && index < Size) {arr[index] = value;}}void display() {for (int i = 0; i < Size; ++i) {cout << arr[i] << " ";}cout << endl;}
};int main() {Array<int, 5> arr1;  // int 类型, 数组大小为 5arr1.set(0, 100);arr1.set(1, 200);arr1.display();  // 输出:100 200 0 0 0
}

说明:

  • 第二个模板参数 Size 是编译期常量(这里是 int),用来定义数组大小。
  • 非类型模板参数必须是编译期已知的常量。

2.3 模板模板参数(Template Template Parameter)

模板参数本身也可以是一个模板,比如容器类中使用的容器类型就可以作为参数。

示例:

#include <iostream>
#include <vector>
#include <list>
using namespace std;template <template <typename, typename> class Container, typename T>
class DataHolder {
private:Container<T, allocator<T>> data;
public:void add(const T& value) { data.push_back(value); }void show() {for (const auto& item : data)cout << item << " ";cout << endl;}
};int main() {DataHolder<vector, int> vHolder;  // 使用 vectorDataHolder<list, int> lHolder;    // 使用 listvHolder.add(1);vHolder.add(2);vHolder.show();  // 输出:1 2lHolder.add(3);lHolder.add(4);lHolder.show();  // 输出:3 4
}

说明:

  • 第一个模板参数 Container 本身是一个模板(如 std::vector)。
  • 必须完整写出 template <typename, typename> 来匹配容器的模板定义。

3. 类模板的默认参数

类模板的参数和函数一样,可以有默认值。

示例:

#include <iostream>
using namespace std;template <typename T = int, int Size = 10>
class FixedArray {
private:T arr[Size];
public:void fill(const T& value) {for (int i = 0; i < Size; ++i)arr[i] = value;}void show() {for (int i = 0; i < Size; ++i)cout << arr[i] << " ";cout << endl;}
};int main() {FixedArray<> a1;            // 使用默认 T=int, Size=10FixedArray<double, 5> a2;   // 自定义类型和大小a1.fill(7);a1.show();a2.fill(3.14);a2.show();
}

4. 部分特化(Partial Specialization)

有时我们希望针对某种特定的模板参数组合提供特殊实现,这时可以使用类模板特化。

示例:

#include <iostream>
using namespace std;template <typename T, typename U>
class MyPair {
public:void show() {cout << "General template" << endl;}
};// 针对第二个参数为 int 的特化
template <typename T>
class MyPair<T, int> {
public:void show() {cout << "Specialized for second parameter int" << endl;}
};int main() {MyPair<double, char> p1;MyPair<float, int> p2;p1.show();  // General templatep2.show();  // Specialized for second parameter int
}

5. 总结

类模板参数的灵活性让我们能够编写高度通用的类

  • 类型参数typename T)是最常用的,适用于泛型数据结构。
  • 非类型参数可以让结构在编译期固定某些常量,提升性能和安全性。
  • 模板模板参数适用于设计可接受不同容器或其他模板的泛型类。
  • 类模板也支持默认参数特化部分特化,让我们可以针对特定需求优化实现。

如果你希望在项目中写出高可复用性的代码,理解并灵活运用类模板参数将大有裨益。

http://www.xdnf.cn/news/19669.html

相关文章:

  • webpack打包优化都有哪些
  • PromptHunt- 简单易用的AI提示词网站
  • PowerPoint和WPS演示如何循环放映PPT
  • uni-app iOS 性能监控与调试全流程:多工具协作的实战案例
  • 【Element-Plus】媒体预览模态框优化实战:从复杂到简洁的设计之路
  • 江协科技STM32学习笔记补充之002 对比介绍 I²C 和 SPI 两种常见的串行总线接口
  • hive udf 执行一次调用多次问题
  • 鸿蒙开发5.0【鸿蒙开发实践】
  • 算法模板(Java版)_前缀和与差分
  • win10虚拟机报错打不开和ubuntu空间不足
  • 深度学习中的数据增强实战:基于PyTorch的图像分类任务优化
  • 【音视频】WebRTC-NetEQ 分析
  • flutter踩坑插件:Swift架构不兼容
  • 深度学习篇---Pytorch常用优化器
  • 网络安全A模块专项练习任务十解析
  • 数据结构:单链表的应用(力扣算法题)第三章
  • ANTD-TABLE表格字段明细展示
  • (MySQL)分布式锁
  • k8s知识点汇总2
  • 【 HarmonyOS 】错误描述:The certificate has expired! 鸿蒙证书过期如何解决?
  • K8S-etcd数据库的相关操作
  • 吴恩达机器学习补充:决策树和随机森林
  • 中越跨境物流管理系统的设计与实现(原创)
  • DiffusionGPT-LLM驱动的文本生成图像系统
  • 【高等数学】第十章 重积分——第五节 含参变量的积分
  • 焦耳热技术助力顶刊研究:薄层质子交换膜实现高效水电解制氢
  • 【STM32】在链接脚本中指定DMA Buffer的地址
  • 智慧班牌系统基于Java+Vue技术栈构建,实现教育信息化综合管理。
  • shell脚本编辑(小白基础学习)
  • 从拿起简历(resume)重新找工作开始聊起