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

C++ 模板(Template)基础与应用

在 C++ 中,**模板(Template)**提供了一种在编译期间生成泛型代码的方法。它类似于其他语言里的“泛型”,允许函数或类在不同类型间复用,而不需要重复编写代码。

1. 函数模板

在没有模板之前,如果想写一个打印不同类型的函数,可能需要为每种类型写一次:

void Print(int value) {std::cout << value << std::endl;
}void Print(std::string value) {std::cout << value << std::endl;
}

这样显得很重复,如果有新的数据类型还要继续写新函数。

使用模板重构

template<typename T>
// 也可以写成 template<class T>
void Print(T value) {std::cout << value << std::endl;
}int main() {Print(5);         // intPrint("Hello");   // const char*Print(5.5);       // double
}

1. 显式指定模板类型

Print<int>(5);

  • 这里我们显式告诉编译器模板类型 Tint

  • 编译器会生成一个函数版本 void Print(int value)

  • 如果你想强制类型,也可以显式指定。


2. 自动类型推导

Print("hello"); Print(5.5f);

  • 编译器会根据传入的参数自动推导模板类型

    • "hello"const char*,所以 T = const char*

    • 5.5ffloat,所以 T = float

  • 你无需手动写 Print<const char*>("hello")Print<float>(5.5f),编译器会自动生成对应的函数版本。

特点:

  • 类型推导:模板类型 T 可以由编译器自动推导,也可以显式指定,例如 Print<int>(5)

  • 延迟生成:模板函数并不是实际存在的函数,只有在调用时才会生成对应类型的函数。

  • 灵活:可以适配任意类型,不用重复编写相同逻辑。


2. 类模板

模板不仅可以用于函数,还可以用于类。例如,我们希望创建一个在栈上存放固定长度数组的类,但数组大小在编译时才能确定:

// size 必须在编译时已知
template<int N>class Array {
private:int m_Array[N];
public:int GetSize() const { return N; }
};int main() {Array<5> array;std::cout << array.GetSize() << std::endl; // 输出 5std::cin.get();
}

调用模板后,编译器会生成对应的类:

class Array {
private:int m_Array[5];
public:int GetSize() const { return 5; }
};

泛型数组

如果希望数组支持任意类型:

template<typename T, int N>class Array {
private:T m_Array[N];
public:int GetSize() const { return N; }
};int main() {Array<int, 5> array;    // int 类型数组,长度为 5std::cout << array.GetSize() << std::endl;std::cin.get();
}
Array<5> array;
  • 模板参数 N 是编译期常量。

  • 编译器会生成固定大小的数组 M m_Array[N];,无需运行时动态分配。

  • 内存连续,访问效率高。

  • 编译器在实例化模板时检查 N 的值,如果写 Array<int, 0> 或负数,会直接报错。

  • 避免运行时错误,提高安全性。

实际上,C++ 标准库中的 std::array<int, 5> 就是类似的实现。


3. 模板的使用建议

  • 函数模板适用于逻辑相同但类型不同的函数,避免重复代码。

  • 类模板适用于类型或大小在编译期可确定的对象,例如数组、容器等。

  • 适度使用模板:过度模板化可能导致编译时间变长或错误信息难以理解。


总结

模板是 C++ 泛型编程的核心工具,它可以在编译期生成类型安全且高效的代码,减少重复、提高代码复用性,同时保持高性能。

http://www.dtcms.com/a/419089.html

相关文章:

  • Flask实战指南:从基础到高阶的完整开发流程
  • I2C总线详解
  • 从底层到应用:开散列哈希表与_map/_set 的完整实现(附逐行注释)
  • MoonBit 异步网络库发布
  • OpenLayers地图交互 -- 章节十六:双击缩放交互详解
  • Kubernetes HPA从入门到精通
  • 株洲做网站的公司网站页面设计
  • 汕头企业网站建设价格视频作为网站背景
  • 视频抽帧完全指南:使用PowerShell批量提取与优化图片序列
  • 1、User-Service 服务设计规范文档
  • 企业网站模板购买企业级网站建设
  • 路由器设置手机网站打不开wordpress跳转二级域名
  • MySQL在线DDL:零停机改表实战指南
  • 哪个做图网站可以挣钱马鞍山网站建设公司排名
  • 杭州公司做网站电商是干什么工作的
  • 揭秘InnoDB磁盘I/O与存储空间管理
  • 【深度相机术语与概念】
  • Android studio 依赖jar包里的类引用时红名,但能构建打包运行。解决红名异常
  • 做设计常用的素材网站网站seo啥意思
  • 云南最便宜的网站建设农村电商平台简介
  • AI时代下,我们需要新一代的金融基础软件
  • 挪威网站后缀网站服务器ip
  • Salesforce 生态中的缓存、消息队列和流处理
  • 【开源】基于STM32的无线条码扫描仪控制系统设计
  • 南京我爱我家网站建设新村二手房有限责任公司和有限公司的区别
  • WebStorm 快捷键大全(Windows / macOS 双平台对照)
  • 多线程顺序输出abc
  • CSS盒模型全面解析
  • 免费开源cms网站源码网页设计公司网站设计
  • [pytest] autouse 参数:自动使用fixture