模板之特化与偏特化

2023-10-31

C++模板

C++模板提供了对逻辑结构相同的数据对象通用行为的定义。这些模板运算对象的类型不是实际的数据类型,而是一种参数化的类型。C++模板分为类模板和函数模板那。
类模板示例:

template <class T>
class TClass
{
public:
    //...
private:
    T member;
};

函数模板示例:

template <class T>
T max(const T a, const T b)
{
    return a > b ? a : b;
}

模板特化

有时,针对特定的类型,需要对模板进行特化,也就是所谓的特殊处理。比如如下代码:

template <class T>
class TClass
{
public:
   bool equal(const T &a, const T &b);
};

template <class T>
bool TClass<T>::equal(const T &a, const T &b)
{
    return (a == b);
}

上述类中只实现了一个equal()方法,用于比较两个参数是否相等。但若用于比较double类型的参数,判断相等需要进行特殊化处理,即要特化模板,代码如下:

#include <math.h>
#include <iostream>

using std::endl;
usging std::cout;

// 已经不具有template的意思了,已经明确为double了
template <>
class TClass<double>
{
public:
    bool equal(const double &a, const double &b);
};

bool TClass<double>::equal(const double &a, const double &b)
{
    return (fabs(a-b) < 10e-3);
}

// 测试代码
int main()
{
    TClass<int> obj_int;
    TClass<double> obj_double;

    cout << obj_int(2, 2) << endl;
    cout << obj_double(2.00003, 2.00001) << endl;

    return 0;
}

模板偏特化

模板偏特化,指提供另一份template定义式,而其本身仍为templatized。也就是说,针对template参数更进一步的条件限制所设计出来的一个特化版本。这种偏特化在STL中随处可见。比如:

template <class _Iterator>
struct iterator_traits
{
     typedef typename _Iterator::iterator_category iterator_category;
     typedef typename _Iterator::value_type        value_type;
     typedef typename _Iterator::difference_type   difference_type;
     typedef typename _Iterator::pointer           pointer;
     typedef typename _Iterator::reference         reference;
};

// specialize for _Tp*
template <class _Tp>
struct iterator_traits<_Tp*> 
{
     typedef random_access_iterator_tag iterator_category;
     typedef _Tp                         value_type;
     typedef ptrdiff_t                   difference_type;
     typedef _Tp*                        pointer;
     typedef _Tp&                        reference;
};

// specialize for const _Tp*
template <class _Tp>
struct iterator_traits<const _Tp*> 
{
     typedef random_access_iterator_tag iterator_category;
     typedef _Tp                         value_type;
     typedef ptrdiff_t                   difference_type;
     typedef const _Tp*                  pointer;
     typedef const _Tp&                  reference;
};

示例代码:

template <class T>
class TestClass
{
public:
    TestClass() { cout << "T" << endl;  }
};

template <class T>
class TestClass<T*>
{
public:
    TestClass() { cout << "T*" << endl;  }
};

template <class T>
class TestClass<const T*>
{
public:
    TestClass() { cout << "const T*" << endl;  }
};

int main()
{
    // 偏特化测试
    TestClass<int> obj_common;
    TestClass<int*> obj_spec1;
    TestClass<const int *> obj_spec2;
}

模板特化与偏特化的区别在于,模板特化以后,实际上其本身已经不是templatized,而偏特化,仍然带有templatized。

特化与偏特化的调用顺序

对于模板、模板的特化和模板的偏特化都存在的情况下,编译器在编译阶段进行匹配时,是如何抉择的呢?从哲学的角度来说,应该先照顾最特殊的,然后才是次特殊的,最后才是最普通的。编译器进行抉择也是尊从这个道理。

转自

https://www.jb51.net/article/56004.htm

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模板之特化与偏特化 的相关文章

随机推荐

  • 网站迁移或者调整页面链接的方法

    背景 这两天我在重新规划我的博客网站逐步前行STEP 将改版导航以及整体内容结构 将单纯的博客网站打造成集博客 资讯 工具 社区于一体的综合站点 这必然涉及到要重新规划原有的路由 直接修改路由将导致搜索引擎收录的链接或者访客收藏的网址失效
  • UNIX网络编程卷一 学习笔记 第十一章 名字与地址转换

    到目前为止 本书中所有例子都用数值地址表示主机 如206 6 226 33 用数值端口号来标识服务器 如端口13代表daytime服务器 但出于某些理由 我们应使用名字而非数值 名字比较容易记住 数值地址可以变动而名字保持不变 随着往IPv
  • ajax基础

    ajax基础 ajax get ajax post ajax get query ajax post body ajax post 用户注册 ajax post 用户登陆 ajax get h1 这是第一个ajax网页 h1
  • OpenMMLab实战营第四课:目标检测与MMDetection

    什么是目标检测 目标检测应用 目标检测vs图像分类 滑窗 Sliding Window 简介 设定一个固定大小的窗口 遍历图像所有位置 所到之处用分类模型 假设已经训练好 识别窗口中的内容 为了检测不同大小 不同形状的物体 可以使用不同大小
  • mseloss pytorch_PyTorch现的一个简单线性回归的样例

    线性回归基本概念 线性回归是利用数理统计中的回归分析来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法 表达形式为y wx e 其中e为误差服从均值为0的正态分布 回归分析中 只包括一个自变量和一个因变量 且二者的关系可用一条直
  • java list 和数组区别_java list和数组的区别

    展开全部 List和ArrayList的区别在于 1 在编程语言中ArrayList类是 Net Framework提供的用于数据存储和检索的专用类 List 类可以简单视之为双向62616964757a686964616fe78988e6
  • ClickHouse之常见的时间周期函数

    文章目录 前言 时区相关 timeZone toTimeZone timeZoneOf 年相关 toYear toStartOfYear toStartOfISOYear toRelativeYearNum toISOYear 季度相关 t
  • VS2008解决“MSVCRT”与其他库的使用冲突的警告

    警告信息如下 1 gt LINK warning LNK4098 默认库 MSVCRT 与其他库的使用冲突 请使用 NODEFAULTLIB library 原因 在使用多线程调试dll MDd 模式的时候 lt 位置 配置属性 c c 代
  • 如何将github项目上传至gitlab

    一 修改远程分支关联 删除远程分支关联 将指向github的远程分支关联关系删除 git remote rm origin 添加新的远程分支关联 新的remote地址指向gitlab相应地址 git remote add origin lt
  • 【中文】【吴恩达课后编程作业】Course 4 - 卷积神经网络 - 第二周作业

    中文 吴恩达课后编程作业 Course 4 卷积神经网络 第二周作业 Keras入门与残差网络的搭建 上一篇 课程4 第二周测验 回到目录 下一篇 课程4 第三周测验 资料下载 下载1 本文所使用的资料已上传到百度网盘 点击下载 15 97
  • 【小程序】为什么使用let that=this

    this 会随着上下文环境而变换它的指向 在当前作用域中设置一个变量用来存储 this 可以防止在其他地方找不到 this 的错误 一般情况 举个例子 btn click function var that this 这里this和that
  • react项目:react拦截器和token问题

    登录获取token后 如何对后面的接口统一在请求头header里面设置token 让后面的请求header都带有token axios拦截器 interceptor 作用 当一个请求发出的时候 会先流过 interceptors 的 req
  • virtualbox禁用硬件虚拟化_Mac版Virtualbox6.1开启嵌套虚拟化

    Virtualbox从6 0版本后 支持起了Intel cpu的嵌套虚拟化 很多用Virtualbox的朋友开始陷入了茫然 为何在BIOS或EFI中开启了CPU硬件虚拟化后 Virtualbox中的vm菜单中启用嵌套虚拟化的框还是灰色不可用
  • 我一下子说出4种分布式ID生成方案,把面试官给搞懵了!

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 上一篇文章 我们聊了一下分库分表相关的一些基础知识 具体可以参见 支撑日活百万用户的高并发系统 应该如何设计其数据库架构 这篇文章 我们就接着分库分表的知识 来具体聊
  • 在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)

    对于游戏公司而言 采用游戏脚本lua python等进行开发也很常见 但是很多童鞋对脚本并没有很熟悉的概念 本篇则向大家简单介绍脚本的用途以及在Cocos2dx基础用法 Lua和python这些详细介绍的话 请不太熟悉的童鞋自行百度百科哈
  • 50道SQL练习题及答案与详细分析:

    流传较广的50道SQL训练 奋斗了不知道多久终于写完了 前18道题的难度依次递增 从19题开始的后半部分算是循环练习和额外function的附加练习 难度恢复到普通状态 第9题非常难 我反正没有写出来 如果有写出来了的朋友还请赐教 这50道
  • 教育平台的线上课程智能推荐策略

    题目来自 http www tipdm org 一 背景 近年来 随着互联网与通信技术的高速发展 学习资源的建设与共享呈现出 新的发展趋势 各种网课 慕课 直播课等层出不穷 各种在线教育平台和学习 应用纷纷涌现 尤其是 2020 年春季学期
  • 用Python学习吴恩达机器学习——梯度下降算法理论篇

    开篇词 CSDN专供 欢迎阅读我的文章 本文起先是在B站上进行投稿 一开始是采用吴恩达机器学习2012年版的 目前已经出了十二期了 现在我决定将我摸索出来的学习笔记在各个平台上进行连载 保证同时更新 半年已过 谁知道AI领域已发生很大的变数
  • ajax获取500,使用Python请求库500获取Ajax Json输出

    import requests import json class Yurtici object baseUrl http www yurticikargo com ajaxRoot1 layouts ArikanliHolding Yur
  • 模板之特化与偏特化

    C 模板 C 模板提供了对逻辑结构相同的数据对象通用行为的定义 这些模板运算对象的类型不是实际的数据类型 而是一种参数化的类型 C 模板分为类模板和函数模板那 类模板示例 template