跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表
C++

C++ 模板详解(进阶)

C++ 模板进阶涵盖非类型模板参数、函数与类模板特化及分离编译机制。非类型参数传递常量值而非类型,支持编译期确定大小。特化允许针对特定类型提供专用实现,包括全特化和偏特化。分离编译涉及多源文件构建流程,模板需处理头文件包含问题以确保实例化可见性。

字节跳动发布于 2026/3/22更新于 2026/5/28 浏览
C++ 模板详解(进阶)

1. 非类型模板参数

模板参数有两种,一种叫类型模板参数,一种叫做非类型模板参数。今天我们来讲讲非类型模板参数。

template <int N> 中的 int N 就是典型的非类型模板参数。这里的 int 是参数的类型,而 N 是参数名,它接收的是一个具体的常量值,而非像普通类型模板参数(如 template <typename T>)那样接收一个'类型'。

两者核心区别就是:

  • 类型模板参数:传递'类型'(如 T = int)
  • 非类型模板参数:传递'常量值'(如 N = 10)

简单来说就是类型模板参数是改变类型,非类型模板参数改变的是类型后面的数。

注意:

  1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
  2. 非类型的模板参数必须在编译期就能确认结果。
// 模板参数 <int N> 就是非类型参数(传递的是'值')
template <int N>
class FixedArray {
private:
    int arr[N]; // 用 N 作为数组长度(编译时就确定了)
public:
    // 打印数组长度
    void printSize() {
        std::cout << "数组长度是:" << N << std::endl;
    }
};

int main() {
    // 实例化时指定具体的'值'(非类型参数)
    FixedArray<3> arr3; // N=3,创建一个长度为 3 的数组
    FixedArray<5> arr5; // N=5,创建一个长度为 5 的数组
    arr3.printSize(); // 输出:数组长度是:3
    arr5.printSize(); // 输出:数组长度是:5
    return 0;
}

2. 类模板的特化

2.1 函数模板特化

模板的特化(Template Specialization)是 C++ 中为模板提供'特殊处理'的机制。简单说就是:当模板的参数满足某种特定条件时,我们可以为它定义一套专门的实现,而不使用通用模板的代码。

比如说下面这个代码,第一个 Print 就是普通的模板,第二个 Print 就是特化的模板。我们要在函数的名字后面加上 <char> 说明我们要特殊处理的是 char 类型的。由于计算机是从上往下编译的,所以当它在 main 函数里面遇到 Print,同时里面是 char 类型的时候,它会自动匹配第二个,然后打印出对应的 ASCII 码。

#include <iostream>

// 通用模板(适用于大多数类型)
template <typename T>
void Print(T value) {
    std::cout << "通用模板:" << value << std::endl;
}

// 对 char 类型的特化版本
template <>
void Print<char>(char value) {
    // 明确指定特化的类型:char
    std::cout << "char 特化:字符 '" << value << "' 的 ASCII 码是 " << (int)value << std::endl;
}

int main() {
    Print(123); // 匹配通用模板,输出:通用模板:123
    Print('A'); // 匹配 char 特化版本,输出:char 特化:字符 'A' 的 ASCII 码是 65
    return 0;
}

2.2 类模板特化

下面这个就是类模板特化中的全特化,简单来说就是给类的每一个参数都传递模板参数,就叫做全特化。

PS:如果只给一个类的部分参数传递模板参数那就是偏特化。

#include <iostream>
#include <string>

// 通用类模板:处理任意类型的数据
template <typename T>
class DataProcessor {
public:
    void process(T data) {
        std::cout << "通用处理:" << data << "(类型未知,按默认方式处理)" << std::endl;
    }
};

// 全特化:专门处理 int 类型
template <>
class DataProcessor<int> {
public:
    void process(int data) {
        std::cout << "int 专用处理:" << data << "(整数翻倍后为 " << data * 2 << ")" << std::endl;
    }
};

// 全特化:专门处理 string 类型
template <>
class DataProcessor<std::string> {
public:
    void process(std::string data) {
        std::cout << "string 专用处理:" << data << "(字符串长度为 " << data.size() << ")" << std::endl;
    }
};

int main() {
    // 测试通用模板(处理 double 类型,没有特化版本)
    DataProcessor<double> dProc;
    dProc.process(3.14); // 用通用模板处理

    // 测试 int 特化版本
    DataProcessor<int> iProc;
    iProc.process(10); // 用 int 专用处理

    // 测试 string 特化版本
    DataProcessor<std::string> sProc;
    sProc.process("hello"); // 用 string 专用处理

    return 0;
}

3. 模板的分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。

这相当于写了一个通用的类,然后我们想用时对他进行调用。

目录

  1. 1. 非类型模板参数
  2. 2. 类模板的特化
  3. 2.1 函数模板特化
  4. 2.2 类模板特化
  5. 3. 模板的分离编译
  • 💰 8折买阿里云服务器限时8折了解详情
  • GPT-5.5 超高智商模型1元抵1刀ChatGPT中转购买
  • 代充Chatgpt Plus/pro 帐号了解详情
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Stable Diffusion 3.5 FP8 在天气变化模拟图像中的动态表现
  • YOLO11 驱动的无人机航拍小目标检测系统实战
  • OJ 题库常见题型与基础算法模式解析
  • AI 产品经理面试指南:核心能力、技术问答与项目实战
  • Java 中 String 对象创建机制解析
  • 冻结语言模型参数进行 Prompt 微调的技术解析
  • React K 线图组件与股票数据 SDK 实现方案
  • OpenClaw 与本地千问模型搭建电脑 AI 助理
  • 机器学习核心算法实战笔记:从 KNN 到集成学习
  • PHP 对接 DeepSeek API 实现指南
  • Neo4j Windows 环境搭建与安装实战
  • Stable Diffusion WebUI Windows 部署与常见报错解决方案
  • Linux 下 FFmpeg C++ 音视频解码与推流实战
  • Kubernetes 中部署 Prometheus 实战指南
  • SQLyog 11 注册信息整理
  • Nginx 作为网络出口网关:架构设计与实践指南
  • 深入剖析 Git 原理与使用(上):核心架构与基础操作
  • 统一大型语言模型和知识图谱:研究路线图与未来方向
  • Qwen-VL 多模态大模型在自定义数据上的微调与部署指南
  • KWDB 运维实战:用 SQL 打通 Metrics 与 CMDB 数据链路

相关免费在线工具

  • 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