模版的特化和偏特化

模版的特化与偏特化

模板为什么要特化,因为编译器认为,对于特定的类型,如果你能对某一功能更好的实现,那么就该听你的。

模板分为类模板与函数模板,特化分为全特化与偏特化。全特化就是限定死模板实现的具体类型,偏特化就是如果这个模板有多个类型,那么只限定其中的一部分。

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后面的尖括号中不带任何内容;

模板偏特化是指只给部分模板参数一个具体的类型,来实现这个模板;

时间: 2024-10-21 20:15:53

模版的特化和偏特化的相关文章

模版的完全特化与偏特化

模板为什么要特化,因为编译器认为,对于特定的类型,如果你能对某一功能更好的实现,那么就该听你的. 模板分为类模板与函数模板,特化分为全特化与偏特化.全特化就是限定死模板实现的具体类型,偏特化就是如果这个模板有多个类型,那么只限定其中的一部分. 模版特化:任何针对模版参数进一步进行条件限制设计的特化版本. <<泛型思维>> 完全特化:针对所有的模版参数进行特化. <<c++ primer>> 类模板: template<class T,class N&g

模版的特化与偏特化

Partial Template Specialization能够让你在模板(Template)的所有可能的实体中特化出一组子集. 1.模板的特化(template specialization):    例如,定义如下的一个模板: template<class Window, class Controller> class Widget { ... 泛化实现代码 ... }; 然后你可以像下面那样明确地加以特化: template<> //注意:template后面的尖括号中不带

C++模板的特化与偏特化

最近在看STL的过程中,发现自己对于模板这里的知识有所生疏,因此今日将这部分内容再做整理,以备后忘. 关于C++模板的概念这里不再赘述,默认读者已经具备基础知识. 模板的特化 先看一段代码: #include <iostream> using namespace std;   template <class T> class TClass { public:      bool Equal(const T& arg, const T& arg1); };   tem

模板类的全特化、偏特化

我们先来定义一个普通的模板类 1 template<class T> 2 struct Test 3 { 4 Test(){ cout << "模板类" << endl; } 5 }; 我们再来调用一下: 1 int main() 2 { 3 Test<char> t1; 4 Test<int> t2; 5 Test<int *> t3; 6 return 0; 7 } 输出的结果1: 模板类 模板类 模板类 如果

[转]C++中模板的特化与偏特化

转载自:http://hi.baidu.com/klcdyx2008/blog/item/5adbf77b79f316f90bd1873c.html 1.引言C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现.目前,STL在C++社区中得到了广泛的关注.应用和研究.理解和掌握模板是学习.应用和研究以及扩充STL的基础.而STL模板实例中又充斥着大量的模板特化和偏特化. 2.模板的定义(1) 类模板定义一个栈的类模板,

模板的全特化与偏特化

模板为什么要特化,因为编译器认为,对于特定的类型,如果你能对某一功能更好的实现,那么就该听你的. 模板分为类模板与函数模板,特化分为全特化与偏特化.全特化就是限定死模板实现的具体类型,偏特化就是如果这个模板有多个类型,那么只限定其中的一部分. 先看类模板: [cpp] view plain copy template<typename T1, typename T2> class Test { public: Test(T1 i,T2 j):a(i),b(j){cout<<&quo

模板全特化与偏特化

特化分为全特化与偏特化,全特化就是限定死模板实现的具体类型,偏特化就是如果这个模板有多个类型,那么只限定其中的一部分.本质上,偏特化模板的匹配和选择过程与重载解析非常类似.实际上,在非常复杂的偏特化情况下,编译器可能就是将偏特化直接译成函数,然后直接调用重载解析来处理.重载解析和偏特化匹配都用到了模板参数推导. 例如c++标准库中的类vector的定义 template <class T, class Allocator> class vector { // … // }; template 

C++模板特化与偏特化

C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样显然不利于程序的扩充和维护.C++模板就应运而生.C++的模板提供了对逻辑结构相同的数据对象通用行为的定义.这些模板运算对象的类型不是实际的数据类型,而是一种参数化的类型.C++中的模板分为类模板和函数模板. 类模板如下: #include <iostream>using namespace std;

C++模板编程里的主版本模板类、全特化、偏特化(C++ Type Traits)

1.  主版本模板类 首先我们来看一段初学者都能看懂,应用了模板的程序: 1 #include <iostream> 2 using namespace std; 3 4 template<class T1, class T2> 5 class A{ 6 public: 7 void function(T1 value1, T2 value2){ 8 cout<<"value1 = "<<value1<<endl; 9 cou