C++之模版详解(进阶)

C++之模版详解(进阶)

目录

1. 非类型模板参数

2. 类模板的特化

2.1 函数模板特化

2.2 类模版特化

3. 模板的分离编译


1. 非类型模板参数

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

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

两者核心区别就是:

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

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

注意:1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。2. 非类型的模板参数必须在编译期就能确认结果。

// 模板参数 <int N> 就是非类型参数(传递的是“值”) template <int N> // 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类型的。由于计算机是从上往下编译的,所以当它在mian函数里面遇到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> { // 明确指定特化的类型是 int public: void process(int data) { std::cout << "int 专用处理:" << data << "(整数翻倍后为 " << data * 2 << ")" << std::endl; } }; // 全特化:专门处理 string 类型 template <> class DataProcessor<std::string> { // 明确指定特化的类型是 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. 模板的分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链 接起来形成单一的可执行文件的过程称为分离编译模式,比如说我写的那个boost搜索引擎项目就是分离编译模式。

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

Read more

Ubuntu 24.04 LTS 保姆级教程:安装 NVIDIA 显卡驱动、CUDA 12.5 及 Docker 容器工具包

Ubuntu 24.04 LTS 保姆级教程:安装 NVIDIA 显卡驱动、CUDA 12.5 及 Docker 容器工具包

摘要: 本文为一篇详尽的指南,旨在帮助开发者和研究人员在最新的 Ubuntu 24.04 LTS (Noble Numbat) 系统上,从零开始成功安装 NVIDIA 显卡驱动、CUDA Toolkit 12.5 以及配置 NVIDIA Container Toolkit,从而使 Docker 容器能够利用 GPU 的强大算力。本文适用于深度学习、机器学习、高性能计算等领域的用户。 目录 1. 前言 2. 第一步:环境准备与清理 3. 第二步:添加 NVIDIA CUDA 官方软件源 4. 第三步:安装 NVIDIA 驱动和 CUDA Toolkit 5. 第四步:

By Ne0inhk
Flutter for OpenHarmony:git 纯 Dart 实现的 Git 操作库(在应用内实现版本控制) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:git 纯 Dart 实现的 Git 操作库(在应用内实现版本控制) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter for OpenHarmony:git 纯 Dart 实现的 Git 操作库(在应用内实现版本控制) 深度解析与鸿蒙适配指南 前言 Git 通常作为命令行工具存在。但在某些特殊场景下,你可能需要在 App 内部直接操作 Git 仓库,例如: * 开发一个手机端的 Git 客户端 App。 * 使用 Git 作为笔记应用(如 Obsidian)的同步后端。 * 在应用内拉取远程配置或 CMS 内容。 git 是一个纯 Dart 实现的 Git 核心库(类似于 Java 的 JGit)。它负责直接读写

By Ne0inhk

Flutter 三方库 posix 的鸿蒙化适配指南 - 掌控底层系统调用、文件权限管理实战、鸿蒙级系统级工具专家

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 posix 的鸿蒙化适配指南 - 掌控底层系统调用、文件权限管理实战、鸿蒙级系统级工具专家 在鸿蒙跨平台应用开发中,当我们需要实现精密的文件权限操控(如 chmod)、获取系统级用户信息或是管理进程间的信号(Signals)时,高层的 Dart SDK 有时无法提供足够细粒度的控制。如果你需要一种接近 C 语言、直接与鸿蒙内核(Kernel)对话的能力。今天我们要深度解析的 posix——一个旨在为 Dart 提供标准可移植操作系统接口(POSIX)支持的高性能库,正是帮你接管“系统底层主权”的关键插件。 前言 posix 是一套对底层 C 库函数的轻量级封装。它通过 Dart FFI 机制,让你能像写

By Ne0inhk
Flutter for OpenHarmony:lpinyin 汉字转拼音的高效方案(通讯录排序与搜索优化) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:lpinyin 汉字转拼音的高效方案(通讯录排序与搜索优化) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net 前言 在开发中文应用时,汉字转拼音是一个绕不开的高频需求。 最典型的场景包括: * 通讯录排序:将“张三”排在 ‘Z’ 组,将“李四”排在 ‘L’ 组。 * 拼音搜索:用户输入 “wx” 就能搜到 “微信” (Weixin)。 lpinyin 是 Dart 社区中广泛使用的一个汉字转拼音库。它基于庞大的字典库,支持多音字处理、声调转换,且性能优秀。 对于 OpenHarmony 应用,由于系统底层 API(如 Intl)对中文拼音的支持可能存在差异或版本限制,引入一个纯 Dart 实现的拼音库能保证跨平台行为的一致性,确保你的鸿蒙应用在处理中文数据时准确无误。 一、核心原理 lpinyin 的工作原理非常直观:

By Ne0inhk