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

【C++深学日志】C++“类”的完全指南--从基础到实践(一)

【C++深学日志】C++“类”的完全指南--从基础到实践(一)

假想一下,你是一个顶级汽车设计师,你的任务不是亲自拧紧每一个螺丝,而是要设计出一幅“汽车蓝图”,你在图纸上设计了一辆汽车所需的一切:车轮、车灯、V8发动机、方向盘等,你手上这份设计好的蓝图就相当于我们今天要讲的C++中的“类”,它规定了汽车的属性(例如:离合器)和方法(功能:换挡),它本身并不是一辆真正的汽车,只是你的一份设计规划,后续你交付给工厂,工厂按照你的设计蓝图,生产出了一辆汽车,这就是实例化,后续工厂有根据你的蓝图设计了一条流水线,每一辆从流水线上生产下来的车辆,都是里这个蓝图(类)的一个对象,他们都有蓝图定义的属性和功能。在C++中类就充当着蓝图的作用,它定义了对象拥有哪些属性,那么就和我一起来揭开这份“蓝图”的面纱吧。 1.类 1.1.类的定义 类的基本思想是数据抽象和封装,数据抽象是一种依赖于接口和实现的分离式编程技术,类的接口包括用户所能执行的操作,类的实现则是包括类的数据成员、负责接口实现的函数以及定义类所需的各种私有函数。封装实现了类的接口和实现的分离,封装后的类隐藏了他的视线细节,也就是说,

By Ne0inhk
【C++】C++异常

【C++】C++异常

🎬 个人主页:MSTcheng · ZEEKLOG 🌱 代码仓库 :MSTcheng · Gitee 🔥 精选专栏: 《C语言》 《数据结构》 《算法学习》 《C++由浅入深》 💬座右铭:路虽远行则将至,事虽难做则必成! 在前面的文章中,我们已经介绍了C++11的一些新特性。本文将和下一篇一起为大家讲解C++的最后两个重要主题:异常处理和智能指针。 文章目录 * 一、异常的概念及使用 * 1.1异常的概念 * 1.2异常的分类 * 1.3异常的抛出与捕获 * 1.4栈展开 * 1.5 查找匹配的处理代码 * 1.6异常重新抛出 * 1.7异常的安全问题 * 1.8异常规范 * 二、总结 一、异常的概念及使用 1.1异常的概念 异常(Exception)是指在程序执行过程中发生的意外或错误情况,

By Ne0inhk
Rust赋能Android蓝牙协议栈:从C++到安全高效的重构之路

Rust赋能Android蓝牙协议栈:从C++到安全高效的重构之路

在移动设备生态中,蓝牙协议栈是连接物理世界与数字世界的关键桥梁,从无线耳机、智能手环到车载系统,其稳定性、安全性与效率直接决定用户体验。长期以来,Android蓝牙协议栈核心模块基于C++开发,凭借接近硬件的性能优势支撑了数十亿设备的运行。但随着物联网设备爆发式增长、蓝牙5.3/5.4等新协议落地,C++固有的内存安全缺陷与并发管理难题愈发凸显。2021年起,Google开始在Android蓝牙协议栈中引入Rust重构核心模块,这一技术选型并非偶然,而是工程实践中安全与效率平衡的必然结果。 目录 一、Android蓝牙协议栈的C++之困 1.1 内存安全漏洞:蓝牙模块的阿喀琉斯之踵 1.2 并发管理复杂:多设备连接下的稳定性难题 1.3 代码可维护性下降:遗产代码的演进瓶颈 二、Rust:破解困局的关键特性赋能 2.1 所有权模型 2.2 并发安全:无数据竞争的天生优势 2.3 零成本抽象与可维护性:

By Ne0inhk