C++——模板特化和偏特化

类模板的特化 阅读详情

1.引言
C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现。目前,STL在C++社区中得到了广泛的关注、应用和研究。理解和掌握模板是学习、应用和研究以及扩充STL的基础。而STL模板实例中又充斥着大量的模板特化和偏特化。


2.模板的定义
(1) 类模板

定义一个栈的类模板,它可以用来容纳不同的数据类型
说明如下:
template <class T>
class stack {
private:
  list* top;
public:
  stack();
  stack(const stack&);
  ~stack();
  void push(T&);
  T& pop();
  //…
};
上述定义中,template告诉编译器这是一个模板,尖括号中的<class T >指明模板的参数,可以有一个或多个,具体实现时由用户指定,其中template <class T >中的关键字class可以用关键字typename来代替。
类模板的使用除了要在声明时指明模板参数外,其余均与普通的类相同,例如:
stack<int> int_stack;
stack<char> ch_stack;
stack<string> str_stack;
int_stack.push(10);
ch_stack.push(‘z’);
str_stack.push(“c++”);
(2)函数模板
假设现在要定义一个max函数来返回同一类型(这种类型是允许比较的)两个值的最大者.
template<class T>
T mymax(const T& t1,const T& t2)
{ return t1 < t2 ? t2 : t1; }
template <class T>的意义与类模板定义中相同。
模板函数的使用与普通非模板函数使用相同,因为模板函数的参数可以从其传入参数中解析出来。例如:
int highest = mymax(5,10);
char c = mymax(‘a’, ’z’);
mymax(5,10)解析出模板函数参数为int, mymax(‘a’, ’z’)解析出模板函数的参数为char。


3.模板的特化
(1)类模板特化

有时为了需要,针对特定的类型,需要对模板进行特化,也就是特殊处理.例如,stack类模板针对bool类型,因为实际上bool类型只需要一个二进制位,就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的.
template <class T>
class stack {};
template < >
class stack<bool> { //…// };
上述定义中template < >告诉编译器这是一个特化的模板。
(2) 函数模板的特化
看下面的例子
main()
{
  int highest = mymax(5,10);
  char c = mymax(‘a’, ’z’);
  const char* p1 = “hello”;
  const char* p2 = “world”;
  const char* p = mymax(p1,p2);
}
前面两个mymax都能返回正确的结果.而第三个却不能,因为,此时mymax直接比较两个指针p1 和 p2 而不是其指向的内容.
针对这种情况,当mymax函数的参数类型为const char* 时,需要特化。
template <class T>
T mymax(const T t1, const T t2)
{
   return t1 < t2 ? t2 : t1;
}

template <>
const char* mymax(const char* t1,const char* t2)
{
   return (strcmp(t1,t2) < 0) ? t2 : t1;
}
现在mymax(p1,p2)能够返回正确的结果了。


4.模板的偏特化
模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化
(1) 类模板的偏特化
例如c++标准库中的类vector的定义
template <class T, class Allocator>
class vector { // … // };
template <class Allocator>
class vector<bool, Allocator> { //…//};
这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。
(2) 函数模板的偏特化
  严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。
  template <class T> void f(T);  (a)
  根据重载规则,对(a)进行重载
  template < class T> void f(T*);  (b)
  如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。


5.模板特化时的匹配规则
(1) 类模板的匹配规则

最优化的优于次特化的,即模板参数最精确匹配的具有最高的优先权
例子:
template <class T> class vector{//…//}; // (a)  普通型
template <class T> class vector<T*>{//…//};  // (b) 对指针类型特化
template <>   class vector <void*>{//…//};  // (c) 对void*进行特化
每个类型都可以用作普通型(a)的参数,但只有指针类型才能用作(b)的参数,而只有void*才能作为(c)的参数
(2) 函数模板的匹配规则
非模板函数具有最高的优先权。如果不存在匹配的非模板函数的话,那么最匹配的和最特化的函数具有高优先权
例子:
template <class T> void f(T);  // (d)
template <class T> void f(int, T, double); // (e)
template <class T> void f(T*);  // (f)
template <> void f<int> (int) ; // (g)
void f(double);  // (h)
bool b;
int i;
double d;
f(b); // 以 T = bool 调用 (d)
f(i,42,d) // 以 T = int 调用(e)
f(&i) ; // 以 T = int* 调用(f)
f(d);  //  调用(g)我怎么觉得是调用(h)
参考文献
[1] Bjarne Stroustrup, The C++ Programming Language (Special Edition), Addison Wesley,2000
[2] Nicolai M.Josuttis, The C++ Standard Library – A Tutorial and Reference ,Addison Wesley,1999
[3] Stanley Lippman and Josée Lajoie ,C++ Primier, 3rd Edition ,Addison Wesley Longman ,1998

 

转载自:http://blog.youkuaiyun.com/zhang810413/archive/2007/12/18/1948603.aspx

 

补充:

 

Partial Template Specialization能够让你在模板(Template)的所有可能的实体中特化出一组子集.
1.模板的特化(template specialization):
    例如,定义如下的一个模板:
    template<class Window, class Controller>
    class Widget
    {
      ... 泛化实现代码 ...
    };
    然后你可以像下面那样明确地加以特化:
    template<>    //注意:
template后面的尖括号中不带任何内容;
    class Widget<ModalDialog, MyController>
    {
      ... 特化实现代码 ...
    };
    其中ModalDialog和MyController是你自己另外定义的类;有了这个Widget的特化定义之后,如果你以后定义了Widget<ModalDialog, MyController>对象时,编译器就会使用上述的特化定义,如果定义了其它泛型对象,那么编译器就是用原本的泛化定义;这就是模板的特化.

2.Partial Template Specialization(模板偏特化)
    模板特化是通过"给模板中的所有模板参数一个具体的类"的方式来实现的.而模板偏特化则是通过"给模板中的部分模板参数以具体的类,而留下剩余的模板参数仍然使用原来的泛化定义"的方式来实现的;
    比如,就上面的Widget类模板的定义来说,有时候想针对任意的Window来搭配一个特定的MyController类特化Widget,这个时候就需要使用模板偏特化机制了.下面的Widget类模板就是Widget的偏特化定义:
    template<class Window>                        //仍然使用原来的泛化定义;
    class Widget<Window, MyController>            //MyController是具体的类,是特化定义;
    {
      ... 偏特化实现代码 ...
    };
    这就是一个偏特化定义;一个MyController类可以搭配任意一种Window.
    通常在一个类模板的偏特化定义中,你只会特化某些模板参数而留下其它泛化参数.当你在程序中具体实现上述类模板的时,编译器会试着找出最匹配的模板定义.这个寻找过程十分复杂精细,允许你以富有创意的方式来进行偏特化.例如,假设你有一个Button类模板,它有一个模板参数,那么,你不但可以拿任意的Window搭配特定的MyController来特化Widget,还可以拿任意Button搭配特定的MyController来偏特化Widget:
    template<class ButtonArg>
    class Widget<Button<ButtonArg>, MyController>    //使用任意Button搭配具体的类MyContorller
    {
      ... 偏特化实现代码 ...
    };
    模板的偏特化能力很强大.当你实例化一个模板时,编译器会把目前存在的偏特化模板和全特化模板做比较,并找出其中最合适、最匹配的实现.这样,灵活性就很大.但是不幸的是,模板的偏特化机制不能用在函数身上,不论成员函数还是非成员函数.

注意:
1.虽然你可以全特化类模板中的成员函数,但是你不能偏特化他们;
2.你不能偏特化命名空间级别(namespace-level)的函数(non-member).最接近"命名空间级别模板函数"的偏特化机制就是函数重载,那就意味着你对"函数参数"(而非返回值类型或内部所用类型)有很精致的特化能力;
3.特化或全特化时,template后面的尖括号中不带任何内容;

总结:
模板特化/全特化是指给每一个模板参数一个具体的类型,以具体实现这个模板,而且template后面的尖括号中不带任何内容;
模板偏特化是指只给部分模板参数一个具体的类型,来实现这个模板;

 

转载自:http://hi.baidu.com/klcdyx2008/blog/item/5adbf77b79f316f90bd1873c.html


C++模板特化与偏特化:核心区别与工程实践 模板是C++泛型编程的核心机制,通过参数化类型实现代码复用。模板特化(Specialization)允许为特定类型提供定制实现,分为完全特化和偏特化两种形式。完全特化需要指定所有模板参数,而偏特化只需指定部分参数,保留其余泛型能力。这种机制在编译器进行模板实例化时,会按照完全特化→偏特化→主模板的优先级匹配。在工程实践中,模板特化常用于性能优化场景,如为bool类型实现位存储、为特定算法提供SIMD优化等。结合类型特征(type traits)和现代C++特性(如concepts),可以构建更灵活高效的泛型 阅读详情

相关推荐

C++模板的全特化和偏特化

C++模板的全特化与偏特化全特化偏特化例子总结 全特化 全特化一般用于处理有特殊要求的类或者函数,此时依靠泛型模板无法处理这种情况。,因此全特化可以运用在类模板和函数模板当中。其模板参数列表为空。 template<> class A<int, char> {}; template<> void func(int arg) {} 偏特化 对部分参数进行指定初...

kingreturn6的博客 490

模板的特化

模板特化

m0_63852255的博客 3028

避坑指南:大疆智图集群建模中5个90%新手会踩的雷(附错误日志分析)

本文针对大疆智图集群建模功能,总结了新手在部署和运行时极易遇到的五个常见问题,包括共享目录权限与路径、主从节点版本一致性、临时存储路径设置、网络与防火墙配置以及错误日志分析。文章结合具体错误日志,提供了详细的排查步骤和解决方案,旨在帮助用户快速定位并解决问题,充分发挥集群建模的效率优势。

weixin_29238147的博客 335

【C++】模板进阶之 — 模板的特化详细讲解

通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果,需要特殊处理, 比如:实现了一个专门用来进行小于比较的函数模板

weixin_42976474的博客 3215

Calpuff模型实战:从气象数据预处理到污染物扩散模拟全流程指南

本文提供了一份详尽的Calpuff模型实战指南,涵盖从气象数据预处理、地形处理到污染物扩散模拟与结果可视化的全流程。重点解析了Calmet气象场构建、Calpuff核心参数配置,并与AERMOD模型进行对比,帮助环境工程师与科研人员掌握这一强大的三维非稳态拉格朗日扩散模型,以应对复杂地形、海岸熏烟等实际模拟挑战。

s4t5u6v7的博客 458

[Unity Demo]从零开始制作空洞骑士Hollow Knight第四集:制作更多的敌人

大家好久不见,终于放完中秋假期可以回自己家里打代码了,上一期我介绍了为什么和如何导入2D toolkit以及制作一个完整的敌人(就是那只蚊子包括了精灵,动画,状态机行为以及脚本)现在不妨趁热打铁制作更多的敌人。

dangoxiba的博客 1973

C++模板特化和偏特化

1、模板特化的引入 使用模板时会遇到一些特殊的类型需要特殊处理,不能(或不希望)直接使用当前的模板版本时,所以此时我们就需要对该类型定义一个类或函数的特例化版本。 例:当使用一个判断相等的模板函数时 template<class T> bool Isequal(T& p1, T& p2){ return p1 == p2; } ...

king_weng的博客 1069

基于稀疏表示字典学习的图像超分辨率-杨建超论文解析

文章:《Image Super-Resolution via Sparse Representation》 作者:杨建超 信号稀疏的定义: 令字典D的原子个数M,信号维度为N,则有以下三种关系: M = N时,D为完备的; M > N时,D为冗余的; M>>N时, D为过完备的。 图解如下: 借鉴了压缩感知的思想,通过对大量低分辨率图像和高分辨...

ycc18829026593的博客 7637

C++ 模板全特化和偏特化

1. 模板特化按对象类型(类和全局函数)分为两种: 类模板的特化和 全局模板函数的特化; 2. 按特化的类型分全特化和偏特化(也就是多个模板参数可以选定只 特化一个或者多个),全局模板函数的特化不支持偏特化; 3. 全局模板函数的特化需要关注几个重要元素 函数返回值 函数名 形参类型、个数和顺序,eg: template <class T> T max_(const T &, const T &) 4. 类模板的特化需要关注几个重要元素 类名,形参类型和个数,形参的顺序倒不重要了;

hzhxxx的专栏 4018

Python爬虫实战:5分钟搞定Boss直聘数据抓取(附完整代理IP配置)

本文详细介绍了如何使用Python爬虫高效抓取Boss直聘的招聘数据,包括环境配置、反爬策略、数据采集与存储、数据分析等完整流程。通过实战案例,帮助开发者快速掌握招聘市场数据抓取技术,为职业决策提供数据支持。

weixin_30832143的博客 346

Windows 11 安装 OpenClaw(龙虾):不用WSL、不用虚拟机、启动、使用、停止、卸载

本文详解 Windows 11 原生安装 OpenClaw(龙虾)全流程,无需 WSL 或虚拟机。涵盖环境配置、安全警示、模型接入(如通义千问)及技能初始化。提供启动、文件自动化操作、停止与卸载的完整指南,并附常见认证过期解决方案。助您快速部署本地 AI 智能体,实现电脑操作自动化,提升工作效率。

寒水馨 · 轻量级技术文档 · hanshuixin.org 899

C++ 中的模板特化和偏特化

当一般的模板定义对于某些特定类型不能满足要求,或者可以提供更高效的实现时,就可以使用模板特化。它不是完全指定模板参数的具体类型,而是对模板参数的某些特性(如指针类型、引用类型、数组类型等)进行特化。(字符串指针)时,上述比较大小的方式就不合适了,因为直接比较指针的值并不能得到字符串内容大小的比较结果。这可以让我们针对指针类型的数组进行特殊的操作,比如更方便地管理指针数组的内存等。还可以对模板参数的其他特性进行偏特化,比如对数组类型。是指针类型时,就会使用这个偏特化的模板类定义,它的数据成员。

2302_81041084的博客 1006

8、内存交织技术详解

本文详细解析了内存交织技术的基本原理、工作机制及实现方式,探讨了其在提升内存访问速度和系统性能中的关键作用。文章还分析了内存交织的优缺点、实际应用场景以及与其他优化技术的结合应用,并提出了未来发展的可能方向,为理解与运用该技术提供了全面参考。

g9h0i1的博客 549

C++中的模板特化和偏特化

然后进行了偏特化,当 T1 为 int 类型时,新的 Pair 类有一个额外的成员函数 multiply ,用于计算 first 和 second 的乘积。然后针对 bool 类型进行了完全特化,在完全特化的类中可以提供与通用模板不同的实现,比如更高效的存储方式或者特殊的操作方法,以适应 bool 类型的特点。然后对 bool 类型且大小为10的栈进行了完全特化,在特化版本中重新定义了 push 和 pop 等成员函数的具体实现。这种偏特化可以针对特定类型组合进行特殊的处理,以满足不同的需求。

2401_88249494的博客 1266

东方财富个股实时行情爬虫实战:从入门到精通,手把手教你构建股票数据采集系统

在量化投资、股市分析和数据挖掘等领域,获取实时、准确的股票行情数据是第一步也是至关重要的一步。东方财富网作为国内最大的财经门户网站之一,提供了丰富的股票数据和实时行情接口。本文将带你从零开始,构建一个完整的东方财富个股实时行情爬虫系统,涵盖股票代码遍历、JSON接口分析、反爬虫策略应对、数据持久化存储等核心技术点。目录前言一、项目背景与目标1.1 为什么要爬取东方财富数据?1.2 项目目标1.3 技术栈二、接口分析与逆向工程2.1 寻找真实数据接口2.2 简化接口2.3 字段含义对照表三、股票代码获取。

2201_76125261的博客 144

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

C++模板的特化(specialization)和偏特化(partial specialization)

C++模板的特化及偏特化类模板全特化:对类中的某个成员函数进行特化处理类模板的偏特化范围偏特化函数模板全特化:函数模板偏特化: 模板函数和模板类有的时候可能需要对传入的不同类型进行不同的处理,比如说有的模板传入int或double类型都可以处理,但是传入char型则会出错,这时就需要模板特化的方式。 类模板全特化: 全特化即将模板类型里的所有类型参数全部具体指明之后处理,如下 template<typena

weixin_43744293的博客 1万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

什么是 C++ 中的模板特化和偏特化?如何进行模板特化和偏特化?

在 C++ 中,模板提供了一种编写通用代码的方法,可以处理多种数据类型。然而,有时我们需要为特定的类型或特定的模板参数提供特定的实现,这就是模板特化和偏特化的用途。模板特化(Template Specialization):是指为模板的某个特定类型或一组特定类型提供完全独立的实现。当编译器遇到这个特定类型时,会使用特化的版本而不是通用模板。模板偏特化(Template Partial Specialization):是指对模板的某些特定类型参数提供特化的实现,但并非所有模板参数都被特化。

rujiran的博客 323

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

c++模板特化和偏特化

一:模板特化 1.函数模板特化 2.类模板特化 二:模板偏特化 主要是类模板的偏特化,函数模板的偏特化没必要,因为可以通过重载来完成。 1.类模板的偏特化 2.函数模板的重载 ...

admin的博客 577

C++ 中的模板特化和偏特化 如何进行模板特化和偏特化

【代码】 C++ 中的模板特化和偏特化 如何进行模板特化和偏特化。

2301_77891039的博客 417

C++ 模板:全特化和偏特化

在C++中,模板特化(template specialization)是一种强大的功能,允许对模板进行特定情况下的处理。模板特化主要分为全特化和偏特化两种。

Bobowen的博客 975

C++模板全特化和偏特化

模板特化,任何针对模板参数进一步进行条件限制设计的特化版本。《泛型思维》 全特化就是全部特化,即针对所有的模板参数进行特化。《c++ primer》偏特化就是部分特化,即针对部分模板参数进行特化。《c++ primer》 全特化和偏特化的定义不是很严格,所以有的时候不容易让人理解。 全特化 #include <iostream> using namespace std; ...

QQ2558030393的博客 334

C/Cpp / STL / 模板全特化和偏特化

栗子 #include <iostream> template <typename T> struct Test { void Print() { std::cout << "当前型别是 T 。" << std::endl; } }; template <> struct Test<int> // 模板特化 ...

布袋和尚 409

重学C++ (十二) 模板特化和偏特化

一、模板的定义 1.类模板 template class T> class compare { public: bool IsEqual(T t1, T t2) { return t1 == t2; } }; int main() { char str1[] = "Hello"; char str2[] = "Hello";

jiange_zh的博客 8685
上一篇: pImpl的原理
下一篇: C++的异常处理
Savitch
博客等级 码龄16年 84粉丝 130原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值