C++ 模版的特化与偏特化
2016-09-29 11:25
435 查看
C++ 模版的特化与偏特化
2013-04-01 15:55 746人阅读 评论(0) 收藏 举报分类:
UNIX/LINUX C/C++(163)
版权声明:本文为博主原创文章,未经博主允许不得转载。
模版的特化与偏特化
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后面的尖括号中不带任何内容;
4.类模版必须指定模版类型参数,不能如函数模版一样进行推导。
5.类中的成员模版函数和普通的模版函数一样,可以进行参数推导。
总结:
模板特化/全特化是指给每一个模板参数一个具体的类型,以具体实现这个模板,而且template后面的尖括号中不带任何内容;
模板偏特化是指只给部分模板参数一个具体的类型,来实现这个模板;
Demo:TemplateDemo.h(模版需要在头文件定义)
[cpp] view
plain copy
print?
template<typename T1, typename T2>
class Test {
public:
Test(T1 i, T2 j) :
a(i), b(j) {
cout << "模板类" << endl;
}
private:
T1 a;
T2 b;
};
template<>
class Test<int, char> {
public:
Test(int i, char j) :
a(i), b(j) {
cout << "全特化" << endl;
}
private:
int a;
char b;
};
template<typename T2>
class Test<char, T2> {
public:
Test(char i, T2 j) :
a(i), b(j) {
cout << "偏特化" << endl;
}
private:
char a;
T2 b;
};
template<class T1, class T2>
class CoreyT {
public:
typedef int Result;
};
template<class T1>
class CoreyT<T1, char> {
public:
typedef long Result;
};
TemplateDemo.cpp
[cpp] view
plain copy
print?
#include "TemplateDemo.h"
int main(int argc, char* const argv[]) {
[cpp] view
plain copy
print?
Test<double, double> t1(0.1, 0.2);
Test<int, char> t2(1, 'A');
Test<char, bool> t3('A', true);
cout << sizeof(CoreyT<int,char>::Result) << endl;
cout << sizeof(CoreyT<int,int>::Result) << endl;
return 0;
}
类模版的使用的时候,需要直接指定模版参数类型才能准确的使用偏特化。
类中的成员模版函数和普通的模版函数一样;如:
[cpp] view
plain copy
print?
class CoreyTT{
public:
template<class T1,class T2>
T1 say(T1 t1,T2 t2){
return (T1)t1+t2;
}
};
[cpp] view
plain copy
print?
CoreyTT tt;
cout << tt.say(1,2);
可以进行模版参数的推导。
相关文章推荐
- C语言的整型溢出问题
- a++与++a
- C++类模板的三种特化类型
- 简单的C++单例模式
- C/C++中strcpy和strncpy的区别
- 第五周项目五 后缀表达式
- 第五周项目4 数制转换
- Windows使用Eclipse Neon搭建Java C/C++ Python开发环境
- 【C++数据类型】const 引用的几点用法
- C++-Qt【1】-退出程序&静态调试
- [C++]STL
- [书]C语言
- [C++]虚基类,解决多继承造成的二义性
- [C++]继承
- [C++]operator--重载
- [C++]friend友元类-友元函数
- [C++]static
- [C++]匿名对象
- [C++]多个对象构造、析构、构造和析构的顺序
- [c++]深拷贝和浅拷贝