C++——模版(函数模版和类模版)

C++ 模板(Templates)完整介绍

模板是 C++ 中一种强大的泛型编程机制,允许开发者编写与类型无关的代码,从而提高代码的复用性和灵活性。

通过模板,可以避免为不同数据类型重复编写相似的函数或类,实现真正的代码复用。

1. 模板的基本概念

1.1 为什么需要模板?

  • 避免代码重复 :传统函数或类需要为不同数据类型(如 intdoublestring)重复实现相同逻辑。
  • 类型安全:模板在编译时生成特定类型的代码,避免运行时类型错误。
  • 提高效率:减少类型转换和重复代码,提升性能。

1.2 模板的两种形式

  • 函数模板:适用于函数,可以处理多种数据类型。
  • 类模板:适用于类,可以定义通用的类结构。

2. 函数模板

2.1 基本语法

cpp 复制代码
template <typename T>  // 或 template <class T>
T max(T a, T b) {
    return (a > b) ? a : b;
}
  • template <typename T> :声明一个模板,T 是类型参数(可以是 intdoublestring 等)。
  • T max(T a, T b) :定义一个泛型函数,参数和返回值类型均为 T

2.2 使用示例

cpp 复制代码
int main() {
    int a = 5, b = 10;
    double x = 3.14, y = 2.71;

    cout << max(a, b) << endl;    // 输出:10(自动推导 T=int)
    cout << max(x, y) << endl;    // 输出:3.14(自动推导 T=double)
}
  • 自动类型推导 :编译器根据参数类型自动推导 T 的具体类型。
  • 显式指定类型
cpp 复制代码
cout << max<int>(3.14, 2.71);  // 强制 T=int,结果截断为 3

2.3 多个类型参数

cpp 复制代码
template <typename T, typename U>
T min(T a, U b) {
    return (a < b) ? a : b;
}
  • 用途 :适用于参数类型不同的情况(如 intdouble 比较)。

3. 类模板

3.1 基本语法

cpp 复制代码
template <typename T>
class Stack {
private:
    vector<T> data;
public:
    void push(T value) {
        data.push_back(value);
    }
    T pop() {
        T value = data.back();
        data.pop_back();
        return value;
    }
};
  • template <typename T> :声明一个类模板,T 是类型参数。
  • vector<T> :使用泛型类型 T 定义成员变量。

3.2 使用示例

cpp 复制代码
int main() {
    Stack<int> intStack;    // 实例化一个存储 int 的 Stack
    Stack<string> strStack; // 实例化一个存储 string 的 Stack

    intStack.push(42);
    strStack.push("Hello");

    cout << intStack.pop() << endl;  // 输出:42
    cout << strStack.pop() << endl;  // 输出:"Hello"
}
  • 显式指定类型 :必须明确指定 T 的具体类型(如 Stack<int>)。

3.3 模板特化(Template Specialization)

  • 作用:为特定类型提供定制化的实现。
  • 示例
cpp 复制代码
template <>
class Stack<bool> {  // 针对 bool 类型的特化版本
private:
    vector<int> data;  // 用 int 存储 bool(节省空间)
public:
    void push(bool value) {
        data.push_back(value ? 1 : 0);
    }
    bool pop() {
        int value = data.back();
        data.pop_back();
        return value != 0;
    }
};
  • 用途 :优化特定类型的性能或行为(如 bool 类型)。

4. 模板的编译与实例化

4.1 编译过程

  1. 模板定义:编译器看到模板代码,但不立即生成代码。
  2. 实例化 :当使用模板时(如 max(3, 5)Stack<int>),编译器根据具体类型生成对应的代码。
  3. 类型检查 :编译器检查类型是否合法(如 max("a", "b") 会报错,因为 string 没有 > 运算符)。

4.2 显式实例化

cpp 复制代码
template class Stack<double>;  // 强制编译器生成 Stack<double> 的代码
  • 用途:减少编译时间,或确保某些类型被编译。

5. 模板的优缺点

5.1 优点

  • 代码复用:一套代码处理多种数据类型。
  • 类型安全:编译时检查类型,避免运行时错误。
  • 性能优化:无类型转换开销,接近手写代码的效率。

5.2 缺点

  • 编译时间增加:模板代码在每次使用时都会实例化,可能导致编译变慢。
  • 错误信息复杂:模板错误通常难以阅读(尤其是多层嵌套时)。
  • 不支持运行时多态:模板是编译时多态,无法像虚函数那样在运行时动态绑定。
相关推荐
沧海一笑-dj9 小时前
【C++】Visual Studio 2026下载和安装
c++·visual studio·vs·vs2026
长友cy9 小时前
Qt官方示例BluetoothLowEnergyGame源码阅读
开发语言·qt
HugoStudio_SWAN9 小时前
洛谷 P1321 单词覆盖还原——从蜡板上的密信到数字水印
c++·学习·程序人生·算法
草青工作室9 小时前
java-不携带Token也能“打“自己的接口:一个绕开网关鉴权、用 URL 直接调度 SpringMVC 方法的轻量级定时任务方案
java·开发语言
shmily麻瓜小菜鸡9 小时前
JavaScript / TypeScript 易踩坑知识点完全指南 -假值(Falsy Values)完全指南
开发语言·javascript·typescript
Coodor9 小时前
信创系统基于QT5操作NFC读写器
开发语言·qt·智能卡·nfc读写器·yw-607hc
励志不掉头发的内向程序员9 小时前
【LibreCAD 2D架构】从鼠标点击到屏幕像素:LibreCAD绘图架构全链路解析之Action与命令系统
linux·开发语言·c++·qt·学习·系统架构
民乐团扒谱机9 小时前
【超详细】PyQt6 实现 AU 风格波形图编辑器:多级缩放与采样点逐级渲染,附全过程代码
开发语言·python·编辑器·pyqt·audition·时域·频谱图
s_w.h9 小时前
【 linux 】线程互斥与同步
java·linux·服务器·开发语言
码匠许师傅9 小时前
【设计模式精讲】15.享元模式(Flyweight)
c++·设计模式·享元模式·uml