• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

C++模板之特化与偏特化详解

c++ 搞代码 4年前 (2022-01-06) 21次浏览 已收录 0个评论

这篇文章主要介绍了C++模板之特化与偏特化详解,本文讲解了什么是C++模板、模板特化、模板偏特化、特化与偏特化的调用顺序等内容,需要的朋友可以参考下

前言

说到C++模板,这个已经不是什么新东西了,自己在实际开发中也用过;对于C++模板特化和偏特化,对于别人来说,已经不是什么新东西了,但是对于我来说,的确是我的盲区,那天在群里讨论这个问题,自己对于这部分确实没有掌握,又联想到在《STL源码剖析》一书中,对于此也是有着介绍。所以,今天就对此进行详细的总结,以备后忘。

C++模板

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

类模板如下:

代码如下:
#include
using namespace std;
 
template
class TClass
{
public:
     // TClass的成员函数
 
private:
     T DateMember;
};

函数模板如下:

代码如下:
template
T Max(const T a, const T b)
{
     return  a > b ? a : b;
}

模板特化

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

代码如下:
#include
using namespace std;
 
template
class TClass
{
public:
     bool Equal(const T& arg, const T& arg1);
};
 
template
bool TClass::Equal(const T& arg, const T& arg1)
{
     return (arg == arg1);
}
 
int main()
{
     TClass obj;
     cout<<obj.Equal(2, 2)<<endl;
     cout<<obj.Equal(2, 4)<<endl;
}

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

代码如下:
#include
using namespace std;
 
template
class Compare
{
public:
     bool IsEqual(const T& arg, const T& arg1);
};
 
// 已经不具有template的意思了,已经明确为float了
template
class Compare
{
public:
     bool IsEqual(const float& arg, const float& arg1);
};
 
// 已经不具有template的意思了,已经明确为double了
template
class Compare
{
public:
     bool IsEqual(const double& arg, const double& arg1);
};
 
template
bool Compare::IsEqual(const T& arg, const T& arg1)
{
     cout<<"Call Compare::IsEqual”<<endl;
     return (arg == arg1);
}
 
bool Compare::IsEqual(const float& arg, const float& arg1)
{
     cout<<"Call Compare::IsEqual”<<endl;
     return (abs(arg – arg1) <10e-3);
}
 
bool Compare::IsEqual(const double& arg, const double& arg1)
{
     cout<<"Call Compare::IsEqual”<<endl;
     return (abs(arg – arg1) <10e-6);
}
 
int main()
{
     Compare obj;
     Compare obj1;
     Compare 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
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
struct iterator_traits
{
     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
struct iterator_traits
{
     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
using namespace std;
 
// 一般化设计
template
class TestClass
{
public:
     TestClass()
     {
          cout<<"T, T1"<<endl;
     }
};
 
// 针对普通指针的偏特化设计
template
class TestClass
{
public:
     TestClass()
     {
          cout<<"T*, T1*"<<endl;
     }
};
 
// 针对const指针的偏特化设计
template
class TestClass
{
public:
     TestClass()
     {
          cout<<"const T*, T1*"<<endl;
     }
};
 
int main()
{
     TestClass obj;
     TestClass obj1;
     TestClass obj2;
 
     return 0;
}

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

特化与偏特化的调用顺序

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

总结

对于模板的特化和偏特化,我的理解可能也不是很正确。希望大家和我进行探讨。我这里只是对自己的一些理解进行了总结。最后,也希望大家对我的博客提出中肯的建议。我坚信,分享使我们更进步。

以上就是C++模板之特化与偏特化详解的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C++模板之特化与偏特化详解

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址