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

注意:

部分顯式具體化只能用於類模板,不能用於函數模板


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM