模板是C++中一个很重要的特性,写一份代码能用于多种数据类型(包括用户自定义类型)。例如,STL的sort()函数可以用于多种数据类型的排序,类stack可以用作多种数据类型的栈。但是,如果我们想对特定的数据类型执行不同的代码(而不是通用模板)呢?这种情况下就可以使用模板特例化(template
specialization)

一、函数模板特例化

当特例化一个函数模板时,必须为原模板中的每个模板参数都提供实参。使用关键字template后跟一个空尖括号<>,即template <>,以指出我们正在特例化一个模板。

template <typename T>
void fun(T a)
{
cout << "The main template fun(): " << a << endl;
} template <> // 对int型特例化
void fun(int a)
{
cout << "Specialized template for int type: " << a << endl;
} int main()
{
fun<char>('a');
fun<int>(10);
fun<float>(9.15);
return 0;
}

输出结果:

The main template fun(): a
Specialized template for int type: 10
The main template fun(): 9.15

对于除int型外的其他数据类型,都会调用通用版本的函数模板fun(T a);对于int型,则会调用特例化版本的fun(int a)。注意,一个特例化版本的本质是一个实例,而非函数的重载。因此,特例化不影响函数匹配。

二、类模板特例化

除了特例化函数模板,我们还可以特例化类模板。下面是一个简单的例子:

template <typename T>
class Test{
public:
void print(){
cout << "General template object" << endl;
}
}; template<> // 对int型特例化
class Test<int>{
public:
void print(){
cout << "Specialized template object" << endl;
}
}; int main()
{
Test<int> a;
Test<char> b;
Test<float> c;
a.print();
b.print();
c.print();
return 0;
}

输出结果:

Specialized template object
General template object
General template object

另外,与函数模板不同,类模板的特例化不必为所有模板参数提供实参。我们可以只指定一部分而非所有模板参数,这种叫做类模板的偏特化部分特例化(partial specialization)。例如,C++标准库中的类vector的定义:

template <typename T, typename Allocator>
class vector
{
/*......*/
}; // 部分特例化
template <typename Allocator>
class vector<bool, Allocator>
{
/*......*/
};

在vector这个例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。注意,一个类模板的部分特例化版本仍然是一个模板,因为使用它时用户还必须为那些在特例化版本中未指定的模板参数提供实参。

C++学习之模板特例化的更多相关文章

  1. java学习笔记12--国际化

    java学习笔记12--国际化 国际化的操作就是指一个程序可以同时适应多门语言,即:如果现在程序者是中国人,则会以中文为显示文字,如果现在程序的使用者是英国人,则会以英语为显示的文字,也就是说可以通过 ...

  2. Python学习---django模板语法180122

    django模板语法[Template] 模版的组成:  HTML代码+逻辑控制代码  <h1> {{ user_name }} </h1> 逻辑控制代码的组成: 1.变量: ...

  3. CNN学习笔记:池化层

    CNN学习笔记:池化层 池化 池化(Pooling)是卷积神经网络中另一个重要的概念,它实际上是一种形式的降采样.有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见 ...

  4. 【Java Web开发学习】Spring4条件化的bean

    [Java Web开发学习]Spring4条件化的bean 转载:https://www.cnblogs.com/yangchongxing/p/9071960.html Spring4引入了@Con ...

  5. opengl学习-利用模板测试勾画物体轮廓中出现的一个问题

    我在学习OpenGL模板测试勾画物体轮廓的时候,出现了这个问题: 这个出现的原因就是,改变摄像机的时候,每次绘制,上次绘制中模板缓冲区的数据没有清除的原因.也就是在while循环开始的时候,glCle ...

  6. 读书笔记_Effective_C++_条款四十三:学习处理模板化基类的名称

    背景是这样的,有两个不同的公司,然后想设计一个MessageSender,为这两个公司发送不同的消息,既支持明文发送SendClearText,也支持密文发送SendEncryptedText.一种思 ...

  7. Effective C++ -----条款43:学习处理模板化基类内的名称

    可在derived class templates内通过“this->“指涉base class templates内的成员名称,或藉由一个明白写出的”base class资格修饰符”完成.

  8. [EffectiveC++]item43:学习处理模板化基类内的名称

  9. Effective C++ Item 43 学习处理模板化基类内的名称

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:可在derived class templates 内通过 "this-&g ...

随机推荐

  1. 使用SpringMvc的一个注意事项

    在Intelij Idea下,如果在新建项目时使用了自带的模板,那么自动生成的web.xml里的DispatcherServlet配置节点默认的servlet-mapping是这样的: 而习惯上,我们 ...

  2. linux 常用shell命令之wc

    wc:查看文件统计信息 用法:$ wc filename 1. $ wc fileName $ wc fileName X Y Z /Desktop/hello X:表示行数 Y:表示单词数 Z:表示 ...

  3. jQuery中$this和$(this)的区别

    要写一个点击弹窗任意地方,关闭弹窗.点击事件写标签在元素上 onclick =  closepop(this),这时候很容易搞不清楚怎么去获取当前元素 function closepop(e){ va ...

  4. (1)指针、引用、const限定符

    自己看书时的一些理解,可能有错误的地方.随着指针的使用增多,会不断修改这篇文章的内容,过去错误的会用划线划去后保留. 1.对引用.指针.常量引用.指向常量的指针.常量指针的理解 //对引用.指针.常量 ...

  5. Microsoft SQL Server学习(六)--查询语句

    联合查询 use student --建表 create table class_A( id int primary key, name varchar(50), sex char(50), cour ...

  6. HDU_1556_线段树区间更新

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  7. POJ_2239_Selecting Courses

    题意:一周上7天课,每天12节课,学校最多开设300节不同的课,每周每种课可以只有一个上课时间或者多个上课时间(上课内容一样),问一周最多可以选多少节课. 分析:二分图最大匹配,将一周84个时间点和可 ...

  8. 音视频】5.ffmpeg命令分类与使用

    GT其实平时也有一些处理音视频的个人或者亲人需求,熟练使用ffmpeg之后也不要借助图示化软件,一个命令基本可以搞定 G: 熟练使用ffmpeg命令!T :不要死记硬背,看一遍,自己找下规律,敲一遍, ...

  9. 梦想CAD控件安卓参数绘图

    在CAD绘图中,参数化绘图可以帮助我们极大缩短设计时间,用户可以按照设计意图控制绘图对象,这样即使对象发生了变化,具体的关系和测量数据仍将保持不变,能够对几何图形和标注进行控制,可以帮助用户应对耗时的 ...

  10. 官方安装docker-ce步骤

    这里是Centos7安装方式 安装依赖包 $ sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 添加Docker ...