当前位置: 首页 > news >正文

类模板的语法

1. 什么是类模板

  • 类模板(class template)是 “类型的模板”——它将一个或多个类型参数非类型参数抽象出来,让一个“通用的类框架”能在编译期被实例化成针对不同类型或不同值的具体类。

  • 作用:通用代码复用静态多态在容器/工具类实现中最常见


2. 基本语法

// 声明一个带 1 个类型参数 T 的类模板
template <typename T>        
class MyClass {
public:// 成员变量T value;// 构造函数MyClass(const T& v) : value(v) {}// 成员函数void print() const {std::cout << value << std::endl;}
};
  • template <typename T>:告诉编译器,接下来定义的是一个类模板,T 是一个占位类型

  • MyClass<T>:当你写 MyClass<int> 时,编译器会 生成一个名为 MyClass 的实际类


3. 如何使用(实例化)

int main() {// 1) 指定类型参数MyClass<int>  mi(42);mi.print();             // 输出 42MyClass<std::string> ms("Hello");ms.print();             // 输出 Hello// 2) C++17 结构化绑定 + CTAD(类模板参数推导)MyClass m2(3.14);       // 自动推断 T 为 doublem2.print();             // 输出 3.14
}
  • 显式实例化MyClass<int>MyClass<std::string> 都是针对不同类型生成的“真实类”。

  • CTAD(Class Template Argument Deduction):C++17 起,如果构造函数参数能唯一推断模板参数,就可以省略 <...>


4. 多模板参数与非类型模板参数

4.1 多类型参数

template <typename Key, typename Value>
class Pair {
public:Key   first;Value second;Pair(const Key& k, const Value& v) : first(k), second(v) {}
};

使用:

Pair<std::string,int>  p("age", 30);
std::cout << p.first << ": " << p.second << std::endl;

4.2 非类型模板参数

// size 是一个整型常量(编译期已知)
template <typename T, int size>
class FixedArray {T data[size];
public:T& operator[](int i) { return data[i]; }int getSize() const { return size; }
};

使用:

FixedArray<double, 5> arr;
for(int i = 0; i < arr.getSize(); ++i)arr[i] = i * 1.1;

5. 模板的实现分离

  • 头文件.hpp.h 中同时放声明定义,或者

  • .h:声明 + #include "MyClass.tpp"
    .tpp:模板定义(实现)
    因为模板必须在使用点可见实现,才能实例化。

// MyClass.hpp
#pragma once
template<typename T>
class MyClass {T v;
public:MyClass(const T&);void print() const;
};
#include "MyClass.tpp"// MyClass.tpp
#include <iostream>
template<typename T>
MyClass<T>::MyClass(const T& _v) : v(_v) {}
template<typename T>
void MyClass<T>::print() const {std::cout << v << std::endl;
}

6. 模板特化

6.1 完全特化(full specialization)

对某个具体类型做专门实现:

// 通用版本
template<typename T>
struct TypeName { static std::string name() { return "Unknown"; } };// 针对 int 完全特化
template<>
struct TypeName<int> { static std::string name() { return "int"; } };// 用法
std::cout << TypeName<double>::name(); // Unknown
std::cout << TypeName<int>::name();    // int

6.2 偏特化(partial specialization)

对一组类型做专门实现(只针对模板类,函数模板不支持偏特化):

// 针对指针类型的偏特化
template<typename T>
struct TypeName<T*> {static std::string name() { return TypeName<T>::name() + "*"; }
};// 用法
std::cout << TypeName<int*>::name();   // int*

7. 模板模板参数(更高级)

允许把“模板本身”作为参数:

template< template<typename> class Container, typename T >
class Wrapper {Container<T> c;
public:void add(const T& v) { c.insert(c.end(), v); }
};// 使用 vector 作为 Container 模板
Wrapper<std::vector, int> w;
w.add(10);

8. 小结与注意事项

  1. 模板是在编译期展开:每种参数组合都会生成独立代码,可能导致可执行文件变大。

  2. 定义与声明要都可见:否则编译器无法实例化。

  3. 特化:完全特化和偏特化用法不同,偏特化只适用于类模板。

  4. CTAD:C++17 支持类模板参数推导,调用时可省略模板参数列表。

  5. 避免虚函数+模板:模板类加虚函数会多一层复杂度,按需使用。

http://www.lryc.cn/news/583484.html

相关文章:

  • Python标准库:时间与随机数全解析
  • 【面试精讲】I2C 子系统核心结构与常见问题深度解析
  • MySQL 09 普通索引和唯一索引
  • 汽车功能安全-软件单元验证 (Software Unit Verification)【用例导出方法、输出物】8
  • 装配式建筑4.0:当房子像汽车一样被“智造”
  • 解锁DevOps潜力:如何选择合适的CI/CD工作流工具
  • 北京-4年功能测试2年空窗-报培训班学测开-第四十六天
  • Spring AI Alibaba Graph使用案例多节点并行执行
  • Webpack、Vite配置技巧与CI/CD流程搭建全解析
  • CentOS7系统部署Node.js LTS V18.16.0
  • 【自动驾驶】经典LSS算法解析——深度估计
  • 佰力博科技与您浅谈低温介电材料特性及应用分析
  • 科技对生态保育的影响?
  • Oracle存储过程导出数据到Excel:全面实现方案详解
  • 专题一_双指针_三数之和
  • 【基础算法】贪心 (四) :区间问题
  • WIFI协议全解析04:从芯片角度看WiFi协议:ESP32/8266 支持了哪些?
  • SQL 视图与事务知识点详解及练习题
  • ARM汇编编程(AArch64架构)课程 - 第7章:SIMD与浮点运算
  • STIDGCN(时空交互动态图卷积网络)的原理,包括其核心模块的设计思路和工作机制 交通预测是智能交通系统中的一个重要任务
  • python+vue的企业产品订单管理系统
  • Redis:分组与设备在 Redis 中缓存存储设计
  • Redis-哨兵机制doctor环境搭建
  • CSS基础选择器、文本属性、引入方式及Chorme调试工具
  • Linux 测开:日志分析 + 定位 Bug
  • 【图像处理基石】如何检测到画面中的ppt并对其进行增强?
  • deepseek实战教程-第十篇deepseek对MCP协议支持
  • 计算机网络实验——网线的制作和测试
  • 7、整合前几篇插件列表
  • 云成本优化的核心原则与框架