C++—全特化和偏特化

全特化和偏特化

C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,

这一点在STL中有着充分的体现。目前,STL在C++社区中得到了广泛的关注、应用和研究。理解和掌握模板

学习、应用和研究以及扩充STL的基础。而STL模板实例中又充斥着大量的模板特化和偏特化。

模板特化分为两种:

全特化和偏特化

首先我们得先明白一个问题,为什么会有特化这种东西呢?

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

全特化:

那我们就用一个例子开始吧:

[cpp] view plain copy

  1. template<class T>

  2. class A

  3. {

  4. public:

  5. A()

  6. :a(0)

  7. {}

  8. ~A()

  9. {

  10. cout << "这里走了原始的模板"<< endl;

  11. }

  12. protected:

  13. T a;

  14. };

  15. template<>

  16. class A<int>

  17. {

  18. public:

  19. A()

  20. :a(0)

  21. {}

  22. ~A()

  23. {

  24. cout << "这里走了全特化后int的版本" << endl;

  25. }

  26. protected:

  27. int a;

  28. };

  29. void test2()

  30. {

  31. A<char> a;

  32. A<int> b;

  33. }

我们先看看程序运行的结果:

C++全特化和偏特化

我们通过析构函数发现了,A<int> b 走的是我们特化的版本。 而A<char> a走的是原始版本。

这就是全特化,我们对模板的所有参数进行了特化。如果你想学习C/C++可以来这个群,首先是三三零,中间是八五九,最后是七六六,里面有大量的学习资料可以下载。

下面是我调试时实例化b的时候,发生的事情,程序走的是int类型特化版本,有图有真相:

C++全特化和偏特化

偏特化:

所谓的偏特化也称局部特化,大家大概明白什么回事了吧。 全特化是所有的模板参数都被进行特化

,偏特化也就是局部的参数特化,看看下面这个例子吧:

[cpp] view plain copy print?

  1. template <typename T1, typename T2>

  2. class Data

  3. {

  4. public:

  5. Data();

  6. private:

  7. T1 _d1;

  8. T2 _d2;

  9. };

  10. template <typename T1, typename T2>

  11. Data<T1, T2>::Data()

  12. {

  13. cout << "Data<T1, T2>" << endl;

  14. }

  15. // 局部特化第二个参数

  16. template <typename T1>

  17. class Data <T1, int>

  18. {

  19. public:

  20. Data();

  21. private:

  22. T1 _d1;

  23. int _d2;

  24. };

  25. template <typename T1>

  26. Data<T1, int>::Data()

  27. {

  28. cout << "Data<T1, int>" << endl;

  29. }

  30. void test2()

  31. {

  32. Data<double, int> d1;

  33. Data<int, double> d2;

  34. }

  35. int main()

  36. {

  37. test2();

  38. system("pause");

  39. return 0;

  40. }

我们观察输出的结果:

C++全特化和偏特化

我画一张图帮我们理解吧:

C++全特化和偏特化

下面我再举个例子,你们说说他是偏特化还是全特化:

[cpp] view plain copy print?

  1. template <typename T1, typename T2>

  2. class Data <T1*, T2*>

  3. {

  4. public :

  5. Data();

  6. private :

  7. T1 _d1 ;

  8. T2 _d2 ;

  9. T1* _d3 ;

  10. T2* _d4 ;

  11. };

  12. template <typename T1, typename T2>

  13. Data<T1 *, T2*>:: Data()

  14. {

  15. cout<<"Data<T1*, T2*>" <<endl;

  16. }

  17. // 局部特化两个参数为引用

  18. template <typename T1, typename T2>

  19. class Data <T1&, T2&>

  20. {

  21. public :

  22. Data(const T1& d1, const T2& d2);

  23. private :

  24. const T1 & _d1;

  25. const T2 & _d2;

  26. T1* _d3 ;

  27. T2* _d4 ;

  28. };

  29. template <typename T1, typename T2>

  30. Data<T1 &, T2&>:: Data(const T1& d1, const T2& d2)

  31. : _d1(d1 )

  32. , _d2(d2 )

  33. {

  34. cout<<"Data<T1&, T2&>" <<endl;

  35. }

记住这些都是偏特化,这里就要再引出一个概念,偏特化并不仅仅是指特殊部分参数,而是针对模板参数更

进一步的条件限制所设计出来的一个特化版本。

最后我在说一个注意事项: 模板的全特化和偏特化都是在已经定义的模板基础之上的,不能单独存在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值