C++ 模板特化

1.模板特化的定义

C++中的模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。

1.1函数模板特化

函数模板特化是在一个统一的函数模板不能在所有类型实例下正常工作时,需要定义类型参数在实例化为特定类型时函数模板的特定实现版本。查看如下例:

#include <iostream>
using namespace std;
template<typename T> T Max(T t1,T t2){
    return (t1>t2)?t1:t2;
}

typedef const char* CCP;
template<> CCP Max<CCP>(CCP s1,CCP s2){
    return (strcmp(s1,s2)>0)?s1:s2;
}
int main(){
//调用实例:int Max<int>(int,int)
    int i=Max(10,5);
    //调用显示特化:const char* Max<const char*>(const char*,const char*)
    const char* p=Max<const char*>("very","good");
    cout<<"i:"<<i<<endl;
    cout<<"p:"<<p<<endl;
}

程序正常编译运行结果:  

i:10

p:very

在函数模板显示特化定义(Explicit Specialization Definition)中,显示关键字template和一对尖括号<>,然后是函数模板特化的定义。该定义指出了模板名、被用来特化模板的模板实参,以及函数参数表和函数体。在上面的程序中,如果不给出函数模板Max<T>在T为const char*时的特化版本,那么在比较两个字符串的大小时,比较的是字符串的起始地址的大小,而不是字符串的内容在字典序中先后次序。

1.1.1使用函数重载替代函数模板特化

除了定义函数模板特化版本外,还可以直接给出模板函数在特定类型下的重载形式(普通函数)。使用函数重载可以实现函数模板特化的功能,也可以避免函数模板的特定实例的失效。例如,把上面的模板特化可以改成如下重载函数:

typedef const char* CCP;
CCP Max(CCP s1,CCP s2){
    return (strcmp(s1,s2)>0)?s1:s2;
}

程序运行结果和使用函数模板特化相同。但是,使用普通函数重载和使用模板特化还是有不同之处,主要表现在如下两个方面:

(1)如果使用普通重载函数,那么不管是否发生实际的函数调用,都会在目标文件中生成该函数的二进制代码。而如果使用模板的特化版本,除非发生函数调用,否则不会在目标文件中包含特化模板函数的二进制代码。这符合函数模板的“惰性实例化”准则。

(2)如果使用普通重载函数,那么在分离编译模式下,应该在各个源文件中包含重载函数的申明,否则在某些原文件中就会使用模板实例化,而不是重载函数。

1.3类模板特化

类模板特化类似于函数模板的特化,即类模板参数在某种特定类型下的具体实现。考察如下代码:

#include <iostream>
using namespace std;

template<typename T>class A{
    T num;
public:
    A(){
        num=T(6.6);
    }
    void print(){
        cout<<"A‘num:"<<num<<endl;
    }
};

template<>class A<char*>{
    char* str;
public:
    A(){
        str="A‘ special definition ";
    }
    void print(){
        cout<<str<<endl;
    }
};

int main(){
    A<int> a1; //显示模板实参的隐式实例化
    a1.print();
    A<char*> a2;//使用特化的类模板
    A2.print();
}

  程序输出结果如下:

A‘num:6

A‘ special definition

时间: 2024-08-25 23:12:12

C++ 模板特化的相关文章

C++模板特化编程

在C++中,模板特化是除了类之外的一种封装变化的方法.模板特化可以通过编译器来对不同的模板参数生成不同的代码. 模板特化通常以模板结构体作为载体.常用技法包括:类型定义.静态成员常量定义和静态成员函数定义. 从不同的角度来看待模板特化,模板特化可以扮演以下角色: 一.函数 模板结构体可以被看做一种函数,其参数必须是明确的类型.整数或者变长参数.变长参数展开甚至可以递归. 二.分支 模板结构体可以实现判断模板参数的类型来完成不同的工作.在编程的时候,如果碰到类似“如果类型是A时进行a操作,如果类型

函数模板特化

#include <iostream> template <typename T> T max(T x, T y) { return x > y ? x : y; } //函数模板特化 template <> const char* max(const char* x, const char* y){ return strcmp(x, y) > 0 ? x : y; } int main(){ std::cout << max(1, 2); st

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++程序设计方法4:模板特化

模板参数的具体化/特殊化 有时,有些类型不适用,则需要对模板进行特殊化处理,这称为"模板特化" 对函数模板,如果有多个模板参数,则特化时必须提供所有参数的特例类型,不能部分特化: 如: char *sum(char *,char *); 在函数名后用<>括号括起具体类型 template<> char* sum<char*>(char* a,char* b){...} 由编译器推导出具体的类型,函数名为普通形式: template<> c

C++ Primer 学习笔记_85_模板与泛型编程 --模板特化[续]

模板与泛型编程 --模板特化[续] 三.特化成员而不特化类 除了特化整个模板之外,还可以只特化push和pop成员.我们将特化push成员以复制字符数组,并且特化pop成员以释放该副本使用的内存: template<> void Queue<const char *>::push(const char *const &val) { char *new_item = new char[sizeof(val) + 1]; strncpy(new_item,val,sizeof(

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

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

模板特化和偏模板特化例子(template specialization and partial template specialization)

测试环境: win7 64 g++ 4.8.1 /*********************************************************************************   Copyright (C), 1988-1999, drvivermonkey. Co., Ltd.   File name:    Author: Driver Monkey   Version:    Mail:[email protected]   Date: 2014.04

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

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