类模板特化

主类模板Stack,使用vector构建,实现栈的功能。

template <typename T>
class Stack {
private:
    std::vector<T> elems;
public:
    void push(T const &elem){
        elems.push_back(elem);
    }
    void pop(){
        if(elems.empty()) return;
        elems.pop_back();
    }
    T top() const{
        if(elems.empty()) return;
        return elems.back();
    }
}

若模板参数是string,我们需要使用deque而不是vector来存放栈元素。这需要对类模板进行特化处理。看下面代码段。

template<>
class Stack<std::string> {  //模板参数为特定string
private:
    std::deque<std::string> elems;
public:
    void push(std::string const &elem){
        elems.push_back(elem);
    }
    void pop(){
        if(elems.empty()) return;
        elems.pop_back();
    }
    std::string top() const{
        if(elems.empty()) return;
        return elems.back();
    }
}

实例化后的模板称为特化模板类。在这个代码段中,特化模板类只针对一个具体的类型(std::string),这种特化被称为完全特化。对于完全特化,首行template尖括号中内容应该为空。上述代码用deque完成栈操作。

有完全特化,就有部分特化。看下面代码。

template <typename T>
class Stack<T*> {
private:
    std::list<T*> elems;
public:
    void push(T* &elem){
        elems.push_front(elem);
    }
    .... //same
}

首行声明T为模板参数,行2表示当模板参数需要是指针时,则不使用主类模板,而用特化模板。

一般情况下,设有一个主类模板:

template <typename T1,typename T2,...typename Tn>
class C {
    ...
}

特化的类模板应该具有的形式是:

template <typename P1,typename P2,...typename PN>
class C<type1,type2,...typeN> {
    ...
}

当主类模板的N个模板参数分别具有行2中的类型type1,type2…,时,编译器将使用特化类模板(而不是主类模板)中的代码来进行实例化操作。

行2中的type2(或者其它任意的一个)可以是一个确定的类型比如int,也可以是一个模板参数。对于后一种情形,需要在首行使用typename声明type2是一个类型名。例如:

template <typename T1,typename T2>//主类模板
class Myclass {
    ...
}

则以下代码定义了一个特化类模板,用来处理T2为int的情形:

template <typename T>
class Myclass<T,int> { //T2为int
    ...
}

而下面代码用来处理T1和T2都为指针的情形:

template <typename T1,typename T2>
class Myclass<T1*,T2*> {
    ...
}
时间: 2024-10-29 05:21:06

类模板特化的相关文章

C++ 模板特化以及Typelist的相关理解

近日,在学习的过程中第一次接触到了Typelist的相关内容,比如Loki库有一本Modern C++ design的一本书,大概JD搜了一波没有译本,英文版600多R,瞬间从价值上看到了这本书的价值!!这是题外话.这本书十分经典.其内容对于一个C++新手来说需要时间来理解吸收.在这里记录一下自己的理解.日后发现错误会给予更正.如有有人碰巧看到了.欢迎指正. 参考了http://blog.csdn.net/gatieme/article/details/50953564 整篇内容分了三个部分:1

C++ Primer 学习笔记_84_模板与泛型编程 --模板特化

模板与泛型编程 --模板特化 引言: 我们并不总是能够写出对全部可能被实例化的类型都最合适的模板.某些情况下,通用模板定义对于某个类型可能是全然错误的,通用模板定义或许不能编译或者做错误的事情;另外一些情况下,能够利用关于类型的一些特殊知识,编写比从模板实例化来的函数更有效率的函数. compare函数和 Queue类都是这一问题的好样例:与C风格字符串一起使用进,它们都不能正确工作. compare函数模板: template <typename Type> int compare(cons

c++类模板深度剖析

1.类模板的泛指类型可以定义多个 template <typename T1, typename T2> class Test { public: void add(T1 a, T2, b); }; 使用时: Test<int, float> t1; //T1的泛指类型就是int, T2的泛指类型就是float. 2.类模板的特化类型 (1)意思就是如果定义了一个类模板,这个类模板的参数有多个,但是如果当使用这个类模板的时候,我们传递参数时,参数的类型是一样的话,编译器就会将类模板

C++ 模板特化

1.模板特化的定义 C++中的模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化.模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化. 1.1函数模板特化 函数模板特化是在一个统一的函数模板不能在所有类型实例下正常工作时,需要定义类型参数在实例化为特定类型时函数模板的特定实现版本.查看如下例: #include <iostream> using namespace std; template<typename T> T Max(T t1,T

C++模板之隐式实例化、显示实例化、隐式调用、显示调用和模板特化详解

代码编译运行环境:VS2012+Debug+Win32 模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程.对于函数模板而言,模板实例化之后,会生成一个真正的函数.而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始化.模板的实例化分为隐式实例化和显示实例化. 对函数模板的使用而言,分为两种调用方式,一种是显示模板实参调用(显示调用),一种是隐式模板实参调用(隐式调用).对于类模板的使用而言,没有隐式模板实参和显式模板实参使用的说法,因为类模板的使用必须显

C++ template —— 模板特化(五)

本篇讲解模板特化------------------------------------------------------------------------------------------------------------第12章 特化和重载------------------------------------------------------------------------------------------------------------前面几篇博客讲解了C++模板如何

C++中的类模板详细讲述

一.类模板定义及实例化 1. 定义一个类模板: 1 template<class 模板参数表>2 3 class 类名{4 5 // 类定义......6 7 }: 其中,template 是声明类模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个,可以是类型参数 ,也可以是非类型参数.类型参数由关键字class或typename及其后面的标识符构成.非类型参数由一个普通参数构成,代表模板定义中的一个常量. 例: 1 template<class type,int widt

类模板(四十八)

我们上节博客介绍了泛型编程思想,那么在 C++ 中是否可以将泛型的思想应用于类呢?答案肯定是显而易见的,在 C++ 中的标准库中,就是一些通用的类模板.我们先来看看类模板有哪些特性,它主要是用于存储和组织数据元素,类中数据组织的方式和数据元素的具体类型无关,如:数组类.链表类.Stack 类等.C++ 中将模板的思想应用于类,使得类的实现不关注数据元素的具体类型,而只关注类所需要实现的功能. 在 C++ 中的类模板是以相同的方式处理不同的类型,并且在类声明前使用 template 进行标识.<

C++解析(26):函数模板与类模板

0.目录 1.函数模板 1.1 函数模板与泛型编程 1.2 多参数函数模板 1.3 函数重载遇上函数模板 2.类模板 2.1 类模板 2.2 多参数类模板与特化 2.3 特化的深度分析 3.小结 1.函数模板 1.1 函数模板与泛型编程 C++中有几种交换变量的方法? 交换变量的方法--定义宏代码块 vs 定义函数: 定义宏代码块 优点:代码复用,适合所有的类型 缺点:编译器不知道宏的存在,缺少类型检查 定义函数 优点:真正的函数调用,编译器对类型进行检查 缺点:根据类型重复定义函数,无法代码复