`
美丽的小岛
  • 浏览: 316296 次
  • 性别: 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++模板函数详解:泛型编程与模板特化的应用实例

    内容概要:本文详细介绍了C++模板函数的基本概念及其实际应用。首先定义了一个通用的add模板函数,...阅读建议:重点理解模板函数的语法结构,注意区分普通模板函数与模板特化之间的区别,尝试修改现有代码来加深印象。

    C++模板编程详解:模板函数、类、特化与SFINAE

    内容概要:本文详细介绍了C++中的模板编程技术,包括模板函数、模板类、模板特化、类型推导、SFINAE(Substitution Failure Is Not An Error)以及模板元编程等内容。通过具体的示例代码,帮助读者理解如何编写与...

    C++模版特化

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

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

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

    C++模板详解

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

    数组特化模板类

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

    C++模板与泛型编程详解及应用场景

    内容概要:本文详细介绍了C++的模板与泛型编程,涵盖模板的基础概念、模板特化与偏特化、SFINAE及模板元编程等核心特性。模板功能使得C++不仅支持面向对象编程,还能实现泛型编程,极大地提高了代码的复用性和灵活性...

    如何理解c++模板

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

    C++函数模板详解应用

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

    学习C++中模板及详解

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

    网上找到网文 c++模板

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

    C++ 类模板详解:代码复用与灵活性的新突破

    文章从类模板的基本定义出发,讲解了其与普通类的区别,详细探讨了类模板在简单示例中的使用、成员函数定义的多种方式、多样化的模板参数(包括非类型参数和模板模板参数)、类模板的全特化和偏特化,最后通过 STL ...

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

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

    C++模板说明及使用详解

    ### C++模板说明及使用详解 #### 模板概述 模板是C++中一项非常重要的特性,它允许程序员编写能够处理多种数据类型的通用代码。通过使用模板,开发人员可以创建与特定类型无关的函数和类,从而提高了代码的重用性...

    详解C++ 模板编程

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

Global site tag (gtag.js) - Google Analytics