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

C++ 模板入门:函数模板与类模板

C++ 模板让编译器根据调用自动生成不同数据类型的函数或类,避免重复编写相似代码。函数模板通过 template 声明类型参数,调用时编译器推导或显式指定类型来实例化。类模板需在类型前加模板头,实例化时必须显式给出类型。混用类型时推导可能失败,可通过强转、多参数模板或显式实例化解决。

beaabea发布于 2026/6/29更新于 2026/10/1969 浏览
C++ 模板入门:函数模板与类模板

泛型编程:写出类型无关的代码

模板就像模具

想象一下,用同一个模具压制不同颜色的橡皮泥玩具——泛型编程就是这个思路。你写一份逻辑,编译器帮你生成处理各种数据类型的版本。

在 C 语言里,想交换两个变量的值,得针对 int、double、char 分别写几乎一样的函数:

void Swap(int& x, int& y) {
    int tmp = x;
    x = y;
    y = tmp;
}

void Swap(double& x, double& y) {
    double tmp = x;
    x = y;
    y = tmp;
}

void Swap(char& x, char& y) {
    char tmp = x;
    x = y;
    y = tmp;
}

除了类型名,逻辑完全相同。C++ 的模板就是让你只写一次,让编译器去实例化出各个版本。

函数模板

1. 语法

函数模板代表一个函数家族,与具体类型无关。声明时用 template 关键字,尖括号里放类型参数:

template<typename T1, typename T2, ..., typename Tn>
void FunctionName(T1& a, T2& b) {
    // ...
}

typename 可以换成 class,效果一样。

用模板改写上面的 Swap:

#include <iostream>
using namespace std;

template<typename T>
void Swap(T& x, T& y) {
    T tmp = x;
    x = y;
    y = tmp;
}

int main() {
    int a = 1, b = 2;
    cout << "交换前:a:" << a << " b:" << b << endl;
    Swap(a, b); // 编译器推导 T 为 int
    cout << "交换后:a:" << a << " b:" << b << endl;

    double c = 1.2, d = 23.1;
    cout << "交换前:c:" << c << " d:" << d << endl;
    Swap(c, d); // 编译器推导 T 为 double
    cout << "交换后:c:" << c << " d:" << d << endl;

    return 0;
}

模板本身不是可执行代码,更像一张蓝图。编译器看到 Swap(a, b),推断 T 是 int,就生成一份处理 int 的函数;看到 Swap(c, d),再生成一份 double 版本。

2. 实例化:隐式与显式

用不同参数调用模板的过程叫实例化。最常见的是隐式实例化——你只需调用,编译器自动推导类型。

但碰上混用类型的情况,编译器就懵了:

#include <iostream>
using namespace std;

template<class T>
T Add(const T& x, const T& y) {
    return x + y;
}

int main() {
    int a = 1;
    double b = 2.2;
    Add(a, b); // 错误:T 该是 int 还是 double?
    return 0;
}

解决办法有三种:

  • 强制类型转换:Add(a, (int)b);
  • 多用模板参数:template<class T1, class T2> T1 Add(const T1& x, const T2& y);
  • 显式实例化:直接在调用时指定 T。

显式实例化就是给函数名后加尖括号:

Add<int>(a, b); // T 明确为 int,b 被隐式转换为 int

类模板更常用显式实例化,但函数模板在推导失败时也少不了这一招。

类模板

类模板只是在类名前加上模板声明:

template<class T1, class T2, ..., class Tn>
class ClassName {
    // 成员
};

例如,一个简易栈:

#include <iostream>
using namespace std;

template<typename T>
class Stack {
public:
    Stack(size_t capacity = 4) {
        _array = new T[capacity];
        _capacity = capacity;
        _size = 0;
    }
private:
    T* _array;
    size_t _capacity;
    size_t _size;
};

类型用 T 占位,之后可以实例化成 int 栈、double 栈……比 typedef 灵活得多。

与函数模板不同,类模板实例化不能靠隐式推导,因为没有参数可猜类型,必须显式写出:

Stack<int> st1;   // 存储 int 的栈
Stack<double> st2; // 存储 double 的栈

这种显式指定正是类模板的常规用法。

更多推荐文章

查看全部
  • Zotero 8.0.1 英文文献批量下载与自动化脚本实战
  • OpenClaw 开源 AI Agent 框架技术解析与实战指南
  • WinClaw:Windows 平台 AI 自动化测试与业务处理工具
  • 使用 Portainer 管理 Docker 容器并实现公网远程访问
  • 大模型四大技术架构解析:Prompt、Agent、RAG 与微调
  • 2026年3月18日人工智能早间新闻
  • C++ STL 标准库算法详解
  • 英伟达 Feynman 芯片架构与 NemoClaw 开源智能体平台技术解析
  • 今天 AI 热榜五大重点方向:平台生态、群体智能与评测体系
  • 无人机 RemoteID 合规实战:基于 ArduRemoteID 的开源方案指南
  • 自然语言处理在社交媒体分析中的应用与实战
  • 前端三年后,我辞职去韩国读了个CS硕士
  • 基于FPGA的视频图像实时增强处理系统设计
  • 智能客服情感化升级实战:降低投诉率的技术方案
  • Trae AI IDE 实战:使用 Trae 开发 AI Chatbot 应用
  • 网络安全护网行动与红蓝对抗机制详解
  • 使用 Web Scraper 插件抓取知乎评论数据实战
  • Dify 工作流实战:快速搭建 Web 登录界面
  • Windows 系统 Claude Code Git Bash 依赖修复方案
  • 逻辑回归实战:从基础原理到癌症识别

相关免费在线工具

  • 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

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online

目录

  1. 泛型编程:写出类型无关的代码
  2. 函数模板
  3. 1. 语法
  4. 2. 实例化:隐式与显式
  5. 类模板