跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 模板基础:函数模板与类模板实战

C++ 模板是泛型编程的基础,允许编写与类型无关的代码。涵盖函数模板的格式、实例化方式(隐式推导与显示指定),以及类模板的定义与使用。通过 Swap 和 Stack 示例,解析模板参数作用范围及编译期实例化机制,解决重复代码问题。注意类模板成员函数定义分离时的语法细节及内存管理规范。

性能调优发布于 2026/3/25更新于 2026/10/2681 浏览
C++ 模板基础:函数模板与类模板实战

C++ 模板基础:函数模板与类模板实战

泛型编程简介

在开发中,我们经常遇到需要处理不同类型但逻辑相同的场景。比如交换两个整数、两个浮点数,甚至两个自定义对象。如果为每种类型都写一遍 Swap 函数,不仅代码冗余,维护成本也高。

void Swap(int& left, int& right) { int temp = left; left = right; right = temp; }
void Swap(double& left, double& right) { double temp = left; left = right; right = temp; }
void Swap(char& left, char& right) { char temp = left; left = right; right = temp; }

这种'模具填充'的方式就是泛型编程的核心思想:编写与类型无关的通用代码。C++ 中的模板(Template)正是实现泛型编程的基础工具。

一、函数模板

1. 格式与原理

函数模板的基本结构如下:

template<typename T1, typename T2, ..., typename Tn>
返回类型 函数名 (参数列表) {
    // 函数体
}

注意,typename 是定义模板参数的关键字,虽然也可以用 class 替代,但通常建议用 typename 以示区分。模板参数的作用域仅限于紧随其后的 {} 块。

下面是一个通用的 Swap 实现:

template<typename T>
void Swap(T& left, T& right) {
    T temp = left;
    left = right;
    right = temp;
}

template<typename T1, typename T2>
T1 Func(const T1& x, const T2& y) {
    cout << x << " " << y << endl;
    return x;
}

调用时,编译器会根据实参自动推导出模板参数的实际类型,这个过程称为实例化。

int main() {
    int a = 0, b = 1;
    double c = 1.1, d = 2.2;
    Swap(a, b);
    Swap(c, d);
    // Date d1(1949, 10, 1), d2(2015, 7, 3);
    // Func(1, 2);
    // Func(1, 2.2);
    return 0;
}

实际上,C++ 标准库已经提供了 swap 函数,日常开发中直接调用即可,无需重复造轮子。

2. 函数模板的实例化

实例化主要有两种方式:

  1. 隐式实例化:编译器根据实参类型自动推导。
  2. 显示实例化:在函数名后的 <> 中显式指定类型。
template<typename T>
T Add(const T& left, const T& right) {
    return left + right;
}

template<typename T>
T* Alloc(int n) {
    return new T[n];
}

int main() {
    int a1 = 10, a2 = 20;
    double d1 = 10.1, d2 = 20.2;

    // 隐式推导成功
    cout << Add(a1, a2) << endl;
    cout << Add(d1, d2) << endl;

    // 类型不一致导致推导失败
    // cout << Add(a1, d1) << endl; // 报错:无法确定 T

    // 方案 1:用户强制转换
    cout << Add(a1, (int)d1) << endl;
    cout << Add((double)a1, d1) << endl;

    // 方案 2:显示实例化
    cout << Add<int>(a1, d1) << endl;
    cout << Add<double>(a1, d1) << endl;

    // 某些情况只能显示实例化
    double* p1 = Alloc<double>(10);
    return 0;
}

注意,类型转换会产生临时变量。例如 Add(a1, (int)d1) 中,(int)d1 是右值,所以参数最好加 const 引用以避免不必要的拷贝。

二、类模板

类模板的声明与函数模板类似,但在使用上有些区别。

template<class T1, class T2, ..., class Tn>
class 类模板名 {
    // 成员定义
};

对于普通类,类名即类型;而对于类模板,类名只是模板,必须带上具体类型才构成完整类型,例如 Stack 是模板,Stack 才是类型。

由于构造函数参数可能未包含所有模板参数,编译器无法完全通过构造函数的实参推导出所有模板参数,因此类模板通常都需要显示实例化。

template<class T>
class Stack {
public:
    Stack(int capacity = 4) {
        _a = new T[capacity];
        _capacity = capacity;
        _size = 0;
    }

    void Push(const T& data) {
        // CheckCapacity();
        _a[_size] = data;
        _size++;
    }

    ~Stack() {
        if (_a) {
            delete[] _a; // 注意:new 对应 delete[]
            _a = nullptr;
            _capacity = 0;
            _size = 0;
        }
    }

private:
    T* _a;
    int _capacity;
    int _size;
};

int main() {
    Stack<int> s1;
    Stack<double> s2;
    Stack<char> s3;
    return 0;
}

关于类模板的声明与定义分离:虽然可以分开写在 .h 和 .cpp 中,但在实际工程中,为了避免链接错误,通常建议将类模板的成员函数定义直接放在头文件中,或者确保实例化可见。


以上就是 C++ 模板的基础知识。掌握模板能显著提升代码复用率,减少重复劳动。在实际项目中灵活运用,会让你的设计更加灵活健壮。

目录

  1. C++ 模板基础:函数模板与类模板实战
  2. 泛型编程简介
  3. 一、函数模板
  4. 1. 格式与原理
  5. 2. 函数模板的实例化
  6. 二、类模板

更多推荐文章

查看全部
  • OpenClaw 完全指南:开源 AI 助手部署与配置
  • ToClaw:不只是炫技 AI,更是易用的桌面工具
  • Python 网络爬虫技术详解:原理、实战与最佳实践
  • 强化学习基础:动态规划算法原理与实现
  • C++ 核心特性详解:函数重载、引用、内联函数、auto 与 nullptr
  • WebSocket 客户端实践:重连、心跳与可靠通信
  • 2026 年高校 AIGC 检测新规解读:AI 率合格标准分析
  • 光伏产品缺陷检测 AI 深度学习算法技术方案
  • 基于 Ollama、Llama3.1 与 Open WebUI 搭建本地大模型环境
  • DeepSeek 与 Cursor 协同构建智能代码审查工具实战
  • 字节发布用于序列推荐的分层大模型 HLLM 技术解析
  • GitHub 启用双因素身份验证(2FA)配置指南
  • 16 届蓝桥杯 Java 组省赛真题详解:思路与代码实现
  • Linux 进程内存分配:malloc、brk、mmap 与 overcommit
  • PyCharm 详细安装与配置指南
  • 深入理解 HTML5 Web Workers:提升网页性能的关键技术
  • AI 赋能产品经理:工作流提效与职业转型实战
  • 树莓派 Ubuntu 24.04.3 LTS 安装 OpenClaw 指南
  • Kimi Code AI 编程助手功能特性与集成指南
  • 详解 RabbitMQ 单机多节点集群搭建

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online