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

C++ 中模板元编程与 SFINAE 机制

什么是模板元编程?

用模板来进行编译器计算,运行期直接把结果替换到代码内,如编译器进行斐波那契数列计算,编译器判断是否指针类型;例子:

template <int N>
struct Fib {static constexpr int value = 	Fib<N-1>::value + Fib<N-2>::value;
};// 特化编程,设置边界
template <>
struct Fib<0> {static constexpr int value = 1;
}template <>
struct Fib<1> {static constexpr int value = 0;
};int main() {cout << Fib<10>::value << endl;return 0;
}

模板类型有几种?

模板类型分两种,一种是参数类型,一种是非参数类型

参数类型:用参数类型作为模板参数,泛化不同类型。
template
template

非参数类型:
用常量值作为模板参数,泛化不同常量,计算不同常量的结果;
template
template

模板元编程为什么必须使用静态成员变量?

模板元编程是编译期进行计算,非静态成员变量不能在编译器进行计算,需要运行期才能计算,因为访问非静态成员变量需要类/结构体对象,对象是运行期的产物;
注意:模板非类型参数作为模板参数,是运行非静态成员变量的,

非类型参数有哪些限制:

1)支持的类型限制:支持int, long, char, bool,enum,指针,引用,成员指针
不支持:double,float

2)必须是编译器常量
非类型参数的值必须在编译时确定,不能是运行时变量(比如 int n=5; Fib 会编译报错,因为 n 是运行时变量);
必须用常量表达式传入(如 Fib<5>、Fib<3+2>、constexpr int n=5; Fib)。

模板元编程有哪些用途?

TMP 的典型用途
编译期数值计算(如常量、数组大小、哈希值计算);
类型萃取(Type Traits,如判断类型是否为指针 / 引用 / 数组、提取模板参数等);
条件编译(根据类型 / 数值选择不同的模板实现);
生成复杂代码(如自动生成类成员、序列化逻辑)。

模板特化

模板的特殊版本,用于处理递归的终止条件(避免无限递归);
生成一个完全确定的模板实例。

template <>
struct Fib<1> {static constexpr int value = 0;
};

这就属于模板特化

template <> 是空模板参数列表,为 “模板参数 N=1” 这个特定情况,提供专门的结构体实现。

给类型参数使用还是非类型参数?

核心是「为模板的所有参数指定具体值 / 类型」,和模板参数本身是 “类型” 还是 “非类型” 无关。
非类型和类型都可以有全特化模板;

1. 类型模板参数(typename T)的全特化

// 通用类型模板(模板参数是类型 T)
template <typename T>
struct PrintType {static void print() {cout << "通用类型:" << typeid(T).name() << endl;}
};// 全特化:为 T=int 指定具体实现
template <>
struct PrintType<int> {static void print() {cout << "特化类型:int(整数类型)" << endl;}
};// 全特化:为 T=string 指定具体实现
template <>
struct PrintType<string> {static void print() {cout << "特化类型:string(字符串类型)" << endl;}
};// 全特化:为 T=double 指定具体实现
template <>
struct PrintType<double> {static void print() {cout << "特化类型:double(浮点数类型)" << endl;}
};int main() {PrintType<char>::print();    // 调用通用模板:输出“通用类型:char”PrintType<int>::print();     // 调用 int 全特化:输出“特化类型:int(整数类型)”PrintType<string>::print();  // 调用 string 全特化:输出“特化类型:string(字符串类型)”PrintType<double>::print();  // 调用 double 全特化:输出“特化类型:double(浮点数类型)”return 0;
}

2. 非类型模板参数(int N)的全特化

template <int N> // 模板参数是非类型 int N
struct Fib {static constexpr int value = Fib<N-1>::value + Fib<N-2>::value; // 通用递归逻辑
};// 全特化:为 N=0 指定具体实现(终止条件)
template <>
struct Fib<0> {static constexpr int value = 0;
};// 全特化:为 N=1 指定具体实现(终止条件)
template <>
struct Fib<1> {static constexpr int value = 1;
};

3. 混合模板参数(类型 + 非类型)的全特化

// 混合模板参数:类型 T + 非类型 N
template <typename T, int N>
struct MixTemplate {static void show() {cout << "通用版本:类型=" << typeid(T).name() << ", 非类型=" << N << endl;}
};// 全特化:同时具体化 T=int、N=5(所有参数都确定)
template <>
struct MixTemplate<int, 5> {static void show() {cout << "全特化版本:类型=int, 非类型=5" << endl;}
};// 全特化:同时具体化 T=double、N=3(所有参数都确定)
template <>
struct MixTemplate<double, 3> {static void show() {cout << "全特化版本:类型=double, 非类型=3" << endl;}
};int main() {MixTemplate<char, 2>::show();   // 通用版本:类型=char, 非类型=2MixTemplate<int, 5>::show();    // 全特化版本:类型=int, 非类型=5MixTemplate<double, 3>::show(); // 全特化版本:类型=double, 非类型=3return 0;

三、易混淆点:全特化 vs 偏特化

// 通用模板:T(类型)+ N(非类型)
template <typename T, int N>
struct MixTemplate { ... };// 偏特化:只具体化 N=5,T 仍保留泛化(不是全特化)
template <typename T>
struct MixTemplate<T, 5> { ... };// 全特化:具体化 T=int + N=5(所有参数都确定)
template <>
struct MixTemplate<int, 5> { ... };

全特化的关键是 “全”—— 所有模板参数都要 “落地” 到具体的类型 / 值,和参数本身是 “类型” 还是 “非类型” 无关。

http://www.dtcms.com/a/573893.html

相关文章:

  • 【实用运维工具】一键完成Oracle数据库的健康巡检,生成WORD报告
  • ICLR 2025 Spotlight | 打破AI“黑箱”!最新IIS评分框架:揭示模型性能与可解释性的共生关系
  • Java实现国密算法 SM2 /SM3 /SM4(基于 BouncyCastle)
  • 文件网站建设高新公司网站建设哪家好
  • Zabbix企业级分布式监控系统(上)
  • 深度解析:接口性能优化实战指南
  • 站点创建成功html代码hr表示
  • 一、Netty-高并发IO底层原理(5种主要的IO模型)
  • 网站开发外包 验收c2c有哪些网站
  • Jenkins是什么
  • 建网站公司浩森宇特大连网络营销师招聘网
  • LeetCode - 杨辉三角 / 二叉树的最大深度
  • RV1126 NO.39:OPENCV查找图形轮廓并画框
  • 【第1章>第3节】基于FPGA的图像腐蚀处理算法的Verilog实现
  • 西安电子科技大学信息化建设处网站模板建站排版跟没缓存好似的
  • 神经网络—— 学习与感知器(细节补充)
  • tensorflow 图像分类 之一
  • 自己网站上做淘宝搜索引擎网站开发属于什么行业
  • 查询网站备案号网站如何做免费的推广
  • 编写一个DXE driver 提供遍历pcie设备配置空间的protocol
  • 随笔之工作方法的“术”
  • 淘宝上做进出口网站有哪些我男同同性做视频网站
  • LLM中的选择性注意:从人类聚焦到模型聚焦
  • 从成本到战略:金仓 KingbaseES 的多维度优势与企业数据库选型的核心考量
  • 做pc网站排wordpress载入慢
  • Java注解在Spring Boot中的详细原理与使用情况解析
  • Python + WebSocket 实现实时体育比分系统(含数据库设计与前端演示)
  • 揭阳智能模板建站网站转应用
  • 多个网站 备案吗工作室网站建设要多大内存
  • 借助 TX Text Control:在 .NET C# 中验证 PDF/UA 文档