C++模板

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

类模板如下:


#include <iostream>
using namespace std;

template <class T>
class TClass
{
public:
// TClass的成员函数

private:
T DateMember;
};

函数模板如下:


template <class T>
T Max(const T a, const T b)
{
return a > b ? a : b;
}

模板特化

有时为了需要,针对特定的类型,需要对模板进行特化,也就是所谓的特殊处理。比如有以下的一段代码:


#include <iostream>
using namespace std;

template <class T>
class TClass
{
public:
bool Equal(const T& arg, const T& arg1);
};

template <class T>
bool TClass<T>::Equal(const T& arg, const T& arg1)
{
return (arg == arg1);
}

int main()
{
TClass<int> obj;
cout<<obj.Equal(2, 2)<<endl;
cout<<obj.Equal(2, 4)<<endl;
}

类里面就包括一个Equal方法,用来比较两个参数是否相等;上面的代码运行没有任何问题;但是,你有没有想过,在实际开发中是万万不能这样写的,对于float类型或者double的参数,绝对不能直接使用“==”符号进行判断。所以,对于float或者double类型,我们需要进行特殊处理,处理如下:


#include <iostream>
using namespace std;

template <class T>
class Compare
{
public:
bool IsEqual(const T& arg, const T& arg1);
};

// 已经不具有template的意思了,已经明确为float了
template <>
class Compare<float>
{
public:
bool IsEqual(const float& arg, const float& arg1);
};

// 已经不具有template的意思了,已经明确为double了
template <>
class Compare<double>
{
public:
bool IsEqual(const double& arg, const double& arg1);
};

template <class T>
bool Compare<T>::IsEqual(const T& arg, const T& arg1)
{
cout<<"Call Compare<T>::IsEqual"<<endl;
return (arg == arg1);
}

bool Compare<float>::IsEqual(const float& arg, const float& arg1)
{
cout<<"Call Compare<float>::IsEqual"<<endl;
return (abs(arg - arg1) < 10e-3);
}

bool Compare<double>::IsEqual(const double& arg, const double& arg1)
{
cout<<"Call Compare<double>::IsEqual"<<endl;
return (abs(arg - arg1) < 10e-6);
}

int main()
{
Compare<int> obj;
Compare<float> obj1;
Compare<double> obj2;
cout<<obj.IsEqual(2, 2)<<endl;
cout<<obj1.IsEqual(2.003, 2.002)<<endl;
cout<<obj2.IsEqual(3.000002, 3.0000021)<<endl;
}

模板偏特化

上面对模板的特化进行了总结。那模板的偏特化呢?所谓的偏特化是指提供另一份template定义式,而其本身仍为templatized;也就是说,针对template参数更进一步的条件限制所设计出来的一个特化版本。这种偏特化的应用在STL中是随处可见的。比如:


template <class _Iterator>
struct iterator_traits
{
typedef typename _Iterator::iterator_category iterator_category;
typedef typename _Iterator::value_type value_type;
typedef typename _Iterator::difference_type difference_type;
typedef typename _Iterator::pointer pointer;
typedef typename _Iterator::reference reference;
};

// specialize for _Tp*
template <class _Tp>
struct iterator_traits<_Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};

// specialize for const _Tp*
template <class _Tp>
struct iterator_traits<const _Tp*>
{
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
};

看了了么?这就是模板偏特化,与模板特化的区别在于,模板特化以后,实际上其本身已经不是templatized,而偏特化,仍然带有templatized。我们来看一个实际的例子:


#include <iostream>
using namespace std;

// 一般化设计
template <class T, class T1>
class TestClass
{
public:
TestClass()
{
cout<<"T, T1"<<endl;
}
};

// 针对普通指针的偏特化设计
template <class T, class T1>
class TestClass<T*, T1*>
{
public:
TestClass()
{
cout<<"T*, T1*"<<endl;
}
};

// 针对const指针的偏特化设计
template <class T, class T1>
class TestClass<const T*, T1*>
{
public:
TestClass()
{
cout<<"const T*, T1*"<<endl;
}
};

int main()
{
TestClass<int, char> obj;
TestClass<int *, char *> obj1;
TestClass<const int *, char *> obj2;

return 0;
}

对于输出结果,我这里就不写了,大家可以试一试。

特化与偏特化的调用顺序

对于模板、模板的特化和模板的偏特化都存在的情况下,编译器在编译阶段进行匹配时,是如何抉择的呢?从哲学的角度来说,应该先照顾最特殊的,然后才是次特殊的,最后才是最普通的。编译器进行抉择也是尊从的这个道理。从上面的例子中,我们也可以看的出来,这就就不再举例说明。

文章出自:http://m.jb51.net/show/56004

C++模板特化与偏特化的更多相关文章

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

    1.  主版本模板类 首先我们来看一段初学者都能看懂,应用了模板的程序: 1 #include <iostream> 2 using namespace std; 3 4 template ...

  2. C++中模板的特化与偏特化

    1.引言 C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现.目前,STL在C++社区中得到了广泛的关注.应用和研究.理 ...

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

    转载自:http://hi.baidu.com/klcdyx2008/blog/item/5adbf77b79f316f90bd1873c.html 1.引言C++中的模板分为类模板和函数模板,虽然它 ...

  4. 【校招面试 之 C/C++】第2题 函数模板、类模板、特化、偏特化

    1.C++模板 说到C++模板特化与偏特化,就不得不简要的先说说C++中的模板.我们都知道,强类型的程序设计迫使我们为逻辑结构相同而具体数据类型不同的对象编写模式一致的代码,而无法抽取其中的共性,这样 ...

  5. C++ 模板的全特化与偏特化

    模板为什么要特化,因为编译器认为,对于特定的类型,如果你能对某一功能更好的实现,那么就该听你的. 模板分为类模板与函数模板,特化分为全特化与偏特化.全特化就是限定死模板实现的具体类型,偏特化就是如果这 ...

  6. oop &&GP 模板 ---> 特化和偏特化

    OOP面向对象编程 GP泛型编程(generic programming) 两者的主要区别就是OOP将数据和对数据的操作放在一起, GP就是将数据和操作独立开来 GP:   数据就是container ...

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

    http://cppblog.com/SmartPtr/archive/2007/07/04/27496.html (1) 类模板定义一个栈的类模板,它可以用来容纳不同的数据类型 template & ...

  8. C++模板函数只能全特化不能偏特化

    C++模板函数只能全特化不能偏特化

  9. C++模板显式实例化,隐式实例化,特化(具体化,偏特化)辨析

    最近再次看C++ PRIMER PLUS的时候看到这个部分感觉讲得很烂,前后口径不一致,所以写个辨析让自己明白的同时也希望对此不太清楚的朋友能搞懂. 总结一下,C++只有模板显式实例化(explici ...

随机推荐

  1. el标签 2016-06-05 21:39 477人阅读 评论(15) 收藏

    JSP EL语言定义 E L(Expression Language) 目的:为了使JSP写起来更加简单. 表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP ...

  2. php配置文件php.ini中文详解

    转自:http://www.cnblogs.com/hbl/archive/2008/02/15/1069367.html [PHP] ; PHP还是一个不断发展的工具,其功能还在不断地删减 ; 而p ...

  3. PHP判断图片格式的七种方法小结

    <?php $imgurl = "http://www.jb51.net/images/logo.gif"; //方法1 echo $ext = strrchr($imgur ...

  4. 12 Top Open Source Data Analytics Apps

    1. Hadoop It would be impossible to talk about open source data analytics without mentioning Hadoop. ...

  5. url地址栏参数<==>对象(将对象转换成地址栏的参数以及将地址栏的参数转换为对象)的实用函数

    /** * @author web得胜 * @param {Object} obj 需要拼接的参数对象 * @return {String} * */ function obj2qs(obj) { i ...

  6. 6 获取请求头和URL信息

    @app.route("/req",methods=['GET','POST'])def req(): print(request.headers) #请求头的信息全部在这里面 p ...

  7. python项目管理

    Python 通常没有对应 Java 的 Ant / Maven 这样的 build tool,有一个用于打包的 setuptools / distutils 但也并不完全等价.如果是用来管理依赖包, ...

  8. hdu 4430 Yukari's Birthday (简单数学 + 二分)

    Problem - 4430 题意是,给出蜡烛的数量,要求求出r和k,r是蜡烛的层数,k是每一层蜡烛数目的底数. 开始的时候,没有看清题目,其实中间的那根蜡烛是可放可不放的.假设放置中间的那根蜡烛,就 ...

  9. 【原生JS】切换选项卡

    效果图: HTML: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...

  10. data-属性的作用

    data-用于存储页面或应用程序的私有自定义数据,赋予我们在所有HTML元素上嵌入自定义data属性的能力,存储的数据能被页面的JS利用,以创建更好的用户体验. <div id="bo ...