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

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

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

beaabea发布于 2026/6/29更新于 2026/9/331 浏览
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 的栈

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

目录

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

更多推荐文章

查看全部
  • Java 后端 Web API 开发实战:从架构设计到部署监控
  • GLM-5 发布:开源模型综合排名第一,Agentic 能力与前端细节显著增强
  • Sublime Text 配置 Verilog 开发环境:语法高亮与代码补全
  • Rust 与 WebAssembly 深度实战:在浏览器与 Node.js 中运行高性能代码
  • Rust 异步并发安全与内存管理的最佳实践
  • IntelliJ IDEA 关闭 AI 自动代码补全提示的设置步骤
  • Rust 异步编程的错误处理艺术
  • Redis 配置密码不生效的排查与解决方案
  • Linux Shell 脚本正则表达式基础
  • AI 智能体 Skills 驱动开发:从使用到项目实战详解
  • C++ 多态底层实现机制深度解析
  • Rust WebAssembly 开发实战:构建高性能前端应用
  • Python 中国节假日库 chinese-calendar 使用指南
  • OpenClaw vs Coze/Dify/n8n:AI Agent 工具选型对比
  • 利用浏览器插件 Web Scraper 爬取知乎评论数据
  • Flutter 三方库 eth_sig_util 鸿蒙适配及以太坊签名技术指南
  • GitHub 热榜项目 - 日榜 (2026-02-23)
  • 如何在 Cursor 中使用 MCP 服务
  • 商业活动中人形机器人与机器狗的现场表演与交付验证
  • MySQL 数据库基础核心知识点梳理

相关免费在线工具

  • 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