个人理解这个东西说白了就是当模板类(或函数)的类型参数为某特定值时用对应的特化定义代之。

看个例子吧

#include <iostream>

using namespace std;

template<typename T>
struct is_void {
static const bool value = false;
}; /* 上面的代码定义了一个简单的模板结构is_void的主版本,无论类型参数T是何值,
* 结构体的静态常量成员value的值都是false,这当然是无意义的,我们需要当且
* 仅当类型参数T为void时,value成员的值为true,于是我们定义下面的特化版本
*/ template<>
struct is_void<void> {
static const bool value = true;
}; /* 这里定义了一个is_void结构体的特化版本,将类型参数T固定为void,此时value
* 成员的值被设定为true
*/ int main(int argc, char* argv[]) {
cout << is_void<void>::value << endl;
cout << is_void<int>::value << endl;
cout << is_void<bool>::value << endl;
return ;
}

这段代码输出为:

1

0

0

以上代码中,当is_void结构体的模板类型参数T被指定时,编译器将检查该结构体的主版本及所有特化版本,如果类型参数与某一特化版本匹配,则该特化版本将被调用,如果没有匹配的特化版本,则调用主版本。也就是说如果T的实参为void,与我们定义的特化版本的参数一至,则此特化版本的定义被应用,如果T不是void则按主版本的定义展开。

上面的例子属于全特化(full-specialisation),也就是所有的类型参数都被确定为实际类型,但有时我们可以需要对参数进行部分而不是完全的限定,这便是偏特化(partial template-class specialisation)。

看下面的例子

template<typename T>
struct is_pointer {
static const bool value = false;
}; template<typename T>
struct is_pointer<T*> {
static const bool value = true;
};

这个例子中我们试图判断模板参数T是否是指针类型,如果是则value成员设为true,如果不是则置为false。然而无论T是不是指针都不可能被一一列举,也就是我们不能像第一个例子一样对诸如void*, int*, long*, char* .... 等等等等一一特化,这工作量太吓人了,我要需要一种方式来将指针的情况一次性特化,这就是例子中应用的方式:偏特化。偏特化的写法我想不难理解,但注意两个版本中的T是不一样的,我们可以把特化版本的T换成T2是没有问题的,这时对于is_pointer<int*>来讲,T代表int*,而T2代表的只是int,大家可以揣摩一下。这也就间接说明了主版本和特化版本允许不同个数的模板参数的原因。

再来一个怪异一点的例子

template <typename T>
struct remove_bounds {
typedef T type;
}; template <typename T, size_t N>
struct remove_bounds<T[N]> {
typedef T type;
}; remove_bounds<int>::type a;
remove_bounds<int[]>::type b;
remove_bounds<int[][]>::type c;

remove_bounds也就是将一个数组类型的[n]去掉即得到其基础类型,如果是非数组类型则返回原类型。于是上面的例子中,a是个int类型的变量,而b也是int类型,c有点怪,它不是int[5]类型,而是int[6]类型。这个例子也说明一个问题,特化版本与主版本的类型参数不一定一样,但typename修饰的类型参数个数是一致的。

C++ Template Specialization (模板特化)的更多相关文章

  1. C++ template —— 模板特化(五)

    本篇讲解模板特化-------------------------------------------------------------------------------------------- ...

  2. C++-函数模板特化如何避免重复定义

     我正在用一个基于模板的库源代码,该库包含一些针对特定类型的模板函数特化.类模板,函数模板和模板函数特化都在头文件中.我在我的.cpp文件中 #include 头文件并编译链接工程.但是为了在整个工程 ...

  3. C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解

    模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程.对于函数模板而言,模板实例化之后,会生成一个真正的函数.而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始 ...

  4. C++ Primer 学习笔记_84_模板与泛型编程 --模板特化

    模板与泛型编程 --模板特化 引言: 我们并不总是能够写出对全部可能被实例化的类型都最合适的模板.某些情况下,通用模板定义对于某个类型可能是全然错误的,通用模板定义或许不能编译或者做错误的事情;另外一 ...

  5. C++ Primer 学习笔记_85_模板与泛型编程 --模板特化[续]

    模板与泛型编程 --模板特化[续] 三.特化成员而不特化类 除了特化整个模板之外,还能够仅仅特化push和pop成员.我们将特化push成员以复制字符数组,而且特化pop成员以释放该副本使用的内存: ...

  6. C++程序设计方法4:模板特化

    模板参数的具体化/特殊化 有时,有些类型不适用,则需要对模板进行特殊化处理,这称为“模板特化” 对函数模板,如果有多个模板参数,则特化时必须提供所有参数的特例类型,不能部分特化: 如: char *s ...

  7. C++ template —— 深入模板基础(二)

    上一篇C++ template —— 模板基础(一)讲解了有关C++模板的大多数概念,日常C++程序设计中所遇到的很多问题,都可以从这部分教程得到解答.本篇中我们深入语言特性.------------ ...

  8. C++ 模板特化以及Typelist的相关理解

    近日,在学习的过程中第一次接触到了Typelist的相关内容,比如Loki库有一本Modern C++ design的一本书,大概JD搜了一波没有译本,英文版600多R,瞬间从价值上看到了这本书的价值 ...

  9. 转:C++模板特化的概念

    http://blog.csdn.net/yesterday_record/article/details/7304025 很久没有看C++,在看STL源码剖析时,看到一个function templ ...

随机推荐

  1. 关于Daydream VR的最直白的介绍

    虚拟现实(Virtual Reality),简称虚拟技术,也称虚拟环境,是利用电脑模拟产生一个三度空间的虚拟世界,提供用户关于视觉等感官的模拟,让用户如同身历其境一般,电脑可以立即进行复杂的运算,将精 ...

  2. vsftp配置主动模式和被动模式

    配置文件:/etc/vsftpd/vsftpd.conf 主动模式配置方法: 主动式连接使用的数据通道 connect_from_port_20=YES 支持数据流的被动式连接模式 pasv_enab ...

  3. 使用<input>标签做了两个按钮, 按钮之间间距如何去掉

    遇到的问题: 使用<input>标签做了两个按钮, 按钮之间有个间距不知道怎么去掉. 如下图: 问题解决: <input>是内联块状元素(inline-block); 内联元素 ...

  4. servlet+jdbc+javabean其实跟ssh差不多

    我给的这个架构可以代替ssh的架构进行项目的开发 common中放的是一些公用类 dao中放的是一些对数据的处理 entity其实也就是javabean service中放的是一些抽象类,简单来说抽象 ...

  5. application/json IE 兼容问题

    由于IE系列浏览器把application/json响应视为文件,并尝试下载在网上看了一下,大致了解,只要修改返回的内容的类型(ContentType)即可解决问题. 由于ajax请求,返回类型默认就 ...

  6. maven自动部署到tomcat的问题

    最近需要使用Maven将项目自动部署到Tomcat,在网络上也查找了很多文章,内容大同小异,今天打算在这里给自己做一个小总结 参考网址:http://blog.csdn.net/dilaomimi/a ...

  7. C#与.Net Framework的各种版本和联系

    C#是微软公司发布的一种面向对象的.运行于.NET Framework之上的高级程序设计语言.并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微软公司研究员Anders Hejlsberg的最新 ...

  8. (转)PHP函数spl_autoload_register()用法和__autoload()介绍

      转--http://www.jb51.net/article/29624.htm 又是框架冲突导致__autoload()失效,用spl_autoload_register()重构一下,问题解决 ...

  9. Lucene.net 从创建索引到搜索的代码范例

    关于Lucene.Net的介绍网上已经很多了在这里就不多介绍Lucene.Net主要分为建立索引,维护索引和搜索索引Field.Store的作用是通过全文检查就能返回对应的内容,而不必再通过id去DB ...

  10. 一些iOS笔试题目

    1.什么是arc?(arc是为了解决什么问题诞生的?) 首先解释ARC: automatic reference counting自动引用计数. ARC几个要点: 在对象被创建时 retain cou ...