C++语言基础(19)-模板的显式具体化

应用背景:

例如有下面的函数模板,它用来获取两个变量中较大的一个:

template<class T> const T& Max(const T& a, const T& b){
    return a > b ? a : b;
}

请读者注意a > b这条语句,>能够用来比较 int、float、char 等基本类型数据的大小,但是却不能用来比较结构体变量、对象以及数组的大小,因为我们并没有针对结构体、类和数组重载>

另外,该函数模板虽然可以用于指针,但比较的是地址大小,而不是指针指向的数据,所以也没有现实的意义。

让模板能够针对某种具体的类型使用不同的算法(函数体或类体不同),这在 C++ 中是可以做到的,这种技术称为模板的显示具体化(Explicit Specialization)

一.函数模板的显式具体化

#include <iostream>
#include <string>

using namespace std;

typedef struct {
    string name;
    int age;
    float score;
} STU;


template<typename T>
const T& Max(const T &a, const T &b);

template<>
const STU& Max<STU>(const STU &a, const STU &b);

ostream & operator<<(ostream &out, const STU &stu);


int main() {

    int a = 10;
    int b = 20;
    cout<<Max(a,b)<<endl;


    STU stu1 = {"Jack",16,95.5};
    STU stu2 = {"Mike",17,90.0};
    cout<<Max(stu1,stu2)<<endl;

    return 0;
}


template<typename T>
const T& Max(const T &a, const T &b) {
    return a > b ? a : b;
}

template<>
const STU& Max<STU>(const STU &a, const STU &b) {
    return a.score > b.score ? a : b;
}


ostream & operator<<(ostream &out, const STU &stu) {
    out<<stu.name<<", "<<stu.age<<", "<<stu.score;
    return out;
}

运行结果:

20

Jack,16,95.5

语法格式为:

template<> const STU& Max(const STU& a, const STU& b);

二.类模板显式具体化

#include <iostream>
#include <string>

using namespace std;

template<typename T1, typename T2>
class Point {
public:
    Point(T1 x, T2 y):m_x(x), m_y(y){}
public:
    T1 getX() const {return m_x;}
    void setX(T1 x) {m_x = x;}
    T2 getY() const {return m_y;}
    void setY(T2 y) {m_y = y;}
    void display() const;
private:
    T1 m_x;
    T2 m_y;
};

// 这里要带上模板头
template<typename T1, typename T2>
void Point<T1,T2>::display() const {
    cout<<"x="<<m_x<<", y="<<m_y<<endl;
}


// 类模板显式具体化(针对字符串类型的显式具体化)
template<>
class Point<char *, char *> {
public:
    Point(char *x, char *y):m_x(x), m_y(y){}
public:
    char* getX() const {return m_x;}
    void setX(char *x) {m_x = x;}
    char *getY() const {return m_y;}
    void setY(char *y) {m_y = y;}
    void display() const;
private:
    char *m_x;
    char *m_y;
};


// 注意!这里不能带模板头template<>
void Point<char*, char*>::display() const {
    cout<<"x="<<m_x<<", y="<<m_y<<endl;
}


int main() {

    (new Point<int,int>(10,20))->display();
    (new Point<int, char*>(20,"jack"))->display();
    (new Point<char*,char*>("java","android"))->display();

    return 0;
}

运行结果:

x =10, y = 20

x = 20, y = jack

x = java, y = android

需要注意的是:在类模板的具体化中,成员方法的实例化是不能带模板头template<>的。

三.部分显式具体化

#include <iostream>



using namespace std;

// 类模板
template<typename T1, typename T2>
class Point {
public:
    Point(T1 x, T2 y):m_x(x), m_y(y){}
public:
    T1 getX() const {return m_x;}
    void setX(T1 x){m_x = x;}
    T2 getY() const {return m_y;}
    void setY(T2 y){m_y = y;}
    void display() const;

private:
    T1 m_x;
    T2 m_y;
};


template<typename T1, typename T2>
void Point<T1,T2>::display() const {
    cout<<"x="<<m_x<<", y="<<m_y<<endl;
}


template<typename T2>
class Point<char*, T2> {
public:
    Point(char *x, T2 y):m_x(x), m_y(y){}
public:
    char *getX() const {return m_x;}
    void setX(char *x){m_x = x;}
    T2 getY() const {return m_y;}
    void setY(T2 y){m_y = y;}
    void display() const;
private:
    char *m_x;
    T2 m_y;
};

// 部分显式具体化还是需要加上模板头
template<typename T2>
void Point<char*,T2>::display() const {
    cout<<"x="<<m_x<<" | y="<<m_y<<endl;
}


int main() {

    (new Point<int,int>(10,20))->display();
    (new Point<char*,int>("jack",10))->display();
    (new Point<char*,char*>("java","android"))->display();

    return 0;
}

运行结果:

x = 10, y = 20

x = jack | y = 10

x = java | y = android

注意:

部分显式具体化只能用于类模板,不能用于函数模板

posted @ 2017-07-04 11:07  夜行过客  阅读(3792)  评论(0编辑  收藏  举报