• 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

    注意:

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

  • 相关阅读:
    史上世界上最惨烈的几次股灾!
    做网站的人必须遵守的N大定律,事实上不止做网站
    看士兵突击有感
    中美小学生守则比较
    奥运赞助商及合作伙伴
    sharepoint 备份还原
    sql事务
    javascript 命名空间 类 继承 重载 私有成员和公开成员
    XSLT 学习一
    Web版OutLook,利用POP接收邮件服务器邮件
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/7115640.html
Copyright © 2020-2023  润新知