`
美丽的小岛
  • 浏览: 309387 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

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

    博客分类:
  • c++
  • c
 
阅读更多
这篇文章主要介绍了C++模板之特化与偏特化详解,本文讲解了什么是C++模板、模板特化、模板偏特化、特化与偏特化的调用顺序等内容,需要的朋友可以参考下.

前言

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

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;
}

 

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

特化与偏特化的调用顺序

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

总结

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

分享到:
评论

相关推荐

    模板的 主版本模板类、全特化、偏特化

    ### 模板的主版本模板类、全特化、偏特化详解 #### 一、主版本模板类 在 C++ 模板编程中,**主版本模板类** 是一个非常基础的概念。这类模板通常定义了一组通用的功能,可以通过传递不同类型的参数来实现这些功能...

    C++模版特化

    ### C++模板特化概述与详解 在C++编程语言中,模板特化是一种非常重要的机制,它允许程序员为特定类型的模板提供定制化的实现。本文将深入探讨C++中的类模板特化,尤其是针对单个模板参数的不同特化类型:特化为...

    C++模板与泛型编程详解及实战应用

    主要内容包括模板的概念与优势、函数模板和类模板的声明与实例化、模板元编程、SFINAE原则、模板特化与偏特化、类型推导与auto关键字、模板与递归、模板与多态、类型列表与元组、模板参数包、模板与智能指针、模板与...

    C++模板详解

    C++模板是C++语言中的一个强大特性,它允许程序员编写通用代码,这些代码可以处理多种数据类型。模板是C++中的元编程...通过阅读提供的"C++模板详解.pdf"文档,你将能更全面地掌握这些知识点,提升你的C++编程技能。

    数组特化模板类

    ### 数组特化模板类详解 #### 一、引言 在C++编程语言中,模板是一种非常强大的特性,它允许我们编写通用的代码来处理不同类型的数据。然而,在某些情况下,我们可能希望针对特定的数据类型或者数据结构进行优化。...

    如何理解c++模板

    ### 如何理解C++模板:全面解析类模板与函数模板 #### 一、引言 在计算机编程领域,模板是一种非常强大的工具,特别是在C++这种支持面向对象编程的语言中。本文将详细介绍C++模板的基本概念、分类(包括类模板和...

    C++函数模板详解应用

    ### C++函数模板详解应用 在C++编程中,函数模板是实现代码重用和泛型编程的关键技术之一。本文将详细介绍C++函数模板的基本概念、语法特点以及一些高级用法,帮助读者深入理解并掌握函数模板的应用。 #### 一、...

    学习C++中模板及详解

    **模板的特化与偏特化** 有时候,对于某些特定类型,我们可能需要提供更高效的实现或者不同的行为。这时,我们可以为模板进行特化或偏特化。特化是指为某个特定类型定义一个完全不同的模板实现,而偏特化则是为模板...

    网上找到网文 c++模板

    C++模板还有其他复杂特性,如模板偏特化、模板模板参数、SFINAE原则(Substitution Failure Is Not An Error)等。理解并熟练掌握这些概念对于编写高效、灵活且可重用的C++代码至关重要。 通过阅读《C++模板详解...

    C++模板使用介绍C++模板使用介绍

    ### C++模板使用详解 #### 引言 C++模板是C++编程语言的一个强大特性,它允许程序员编写泛型代码,即可以处理多种数据类型的代码。通过模板,程序员能够编写出灵活、可重用且类型安全的代码,极大地提高了编程效率...

    详解C++ 模板编程

    C++ 模板编程是C++语言中一个强大的特性,它允许程序员编写泛化的代码,以处理多种数据类型。模板分为两种主要类型:类型模板和非类型参数模板。 1. **类型模板**: - **函数模板**:如示例中的`add`函数,它接受...

    C++模板函数重载规则详解

    `HasToString`的工作原理是通过模板特化和模板参数推断来实现的,虽然初看复杂,但其本质是在编译期间生成不同的类型,然后检查这些类型是否可以成功构建。 `constexpr`关键字是C++11引入的,它用于声明一个函数或...

    C++模板与泛型编程入门教程

    ### C++模板与泛型编程入门教程 #### 一、模板的概念与优势 **1.1 概念** C++模板是一种重要的语言特性,用于实现泛型编程。它允许开发者编写能够处理多种数据类型的代码,而不需要为每种类型单独编写相同的逻辑...

    C++模板

    ### C++模板编程详解 #### 一、C++模板简介 C++模板是C++语言的一个强大特性,它允许程序员编写通用代码,这种代码能够处理不同类型的数据,而无需为每种类型都编写相同的代码逻辑。模板可以应用于函数、类以及...

    C++ STL源码详解

    此外,还可以探索STL如何利用C++的特性如模板特化、模板偏特化来实现更灵活的接口。 总之,C++ STL源码分析是一个深入理解C++语言和编程实践的过程,通过这个过程,开发者能够更好地利用STL提供的工具,编写出高效...

    Exceptional C++ 47个疑难问题详解 PDF格式

    书中的问题可能会涉及模板的特化、偏特化、模板元编程以及模板的实例化和展开等高级用法。 2. **异常处理(Exception Handling)**:C++的异常处理机制是保证程序健壮性的重要工具。书中可能讨论了何时、如何抛出和...

    详解C++11 变参模板

    - 变参模板不支持部分特化,只能进行全特化或模板偏特化。 - 参数包不能作为函数返回类型或类的非类型模板参数。 - 在C++11中,参数包的展开发生在模板实例化阶段,而不是在编译器解析代码的时候,这可能导致一些...

Global site tag (gtag.js) - Google Analytics